summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt61
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/cmd_line.xml2
-rw-r--r--indra/newview/app_settings/commands.xml6
-rw-r--r--indra/newview/app_settings/high_graphics.xml41
-rw-r--r--indra/newview/app_settings/key_bindings.xml1
-rw-r--r--indra/newview/app_settings/logcontrol.xml1
-rw-r--r--indra/newview/app_settings/low_graphics.xml41
-rw-r--r--indra/newview/app_settings/mid_graphics.xml41
-rw-r--r--indra/newview/app_settings/settings.xml253
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl298
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl490
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl419
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl)17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl115
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl105
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl92
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl164
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl227
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl169
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/skyV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl101
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl117
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl306
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl239
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl75
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/waterF.glsl192
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/waterF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/waterF.glsl)68
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl251
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl134
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl52
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl119
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl166
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl202
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl106
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl111
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/indirect.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl380
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl195
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl)19
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl323
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl156
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl)29
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl572
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl157
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyF.glsl126
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl261
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl351
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl59
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterV.glsl95
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl)70
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl265
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/transportF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/shader_hierarchy.txt184
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml42
-rw-r--r--indra/newview/character/avatar_skeleton.xml214
-rw-r--r--indra/newview/cube.dae103
-rw-r--r--indra/newview/featuretable.txt83
-rw-r--r--indra/newview/featuretable_mac.txt64
-rw-r--r--indra/newview/installers/windows/installer_template.nsi36
-rw-r--r--indra/newview/installers/windows/lang_da.nsibin11992 -> 12802 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsi4
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin11666 -> 12480 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin12976 -> 13790 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin13492 -> 14302 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin12714 -> 13528 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin9880 -> 10698 bytes
-rw-r--r--indra/newview/installers/windows/lang_pl.nsibin12312 -> 13122 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin13136 -> 13970 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin12450 -> 13264 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin12360 -> 13174 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin9324 -> 10144 bytes
-rw-r--r--indra/newview/licenses-mac.txt52
-rw-r--r--indra/newview/licenses-win32.txt49
-rw-r--r--indra/newview/llagent.cpp34
-rw-r--r--indra/newview/llagentcamera.cpp12
-rw-r--r--indra/newview/llagentpicksinfo.h4
-rw-r--r--indra/newview/llagentwearables.cpp21
-rw-r--r--indra/newview/llappearancemgr.cpp12
-rw-r--r--indra/newview/llappviewer.cpp236
-rw-r--r--indra/newview/llappviewer.h23
-rw-r--r--indra/newview/llaudiosourcevo.cpp36
-rw-r--r--indra/newview/llavataractions.cpp163
-rw-r--r--indra/newview/llavataractions.h28
-rw-r--r--indra/newview/llavatarlist.cpp108
-rw-r--r--indra/newview/llavatarlist.h26
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp254
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h21
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp28
-rw-r--r--indra/newview/llcallingcard.cpp4
-rw-r--r--indra/newview/llchatbar.cpp2
-rw-r--r--indra/newview/llchathistory.cpp69
-rw-r--r--indra/newview/llcolorswatch.cpp18
-rw-r--r--indra/newview/llcontrolavatar.cpp5
-rw-r--r--indra/newview/llcontrolavatar.h1
-rw-r--r--indra/newview/llconversationloglist.cpp3
-rw-r--r--indra/newview/llconversationmodel.cpp1
-rw-r--r--indra/newview/llconversationview.cpp47
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp7
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h1
-rw-r--r--indra/newview/lldrawable.cpp7
-rw-r--r--indra/newview/lldrawable.h1
-rw-r--r--indra/newview/lldrawpool.cpp24
-rw-r--r--indra/newview/lldrawpool.h163
-rw-r--r--indra/newview/lldrawpoolalpha.cpp359
-rw-r--r--indra/newview/lldrawpoolalpha.h15
-rw-r--r--indra/newview/lldrawpoolavatar.cpp8
-rw-r--r--indra/newview/lldrawpoolbump.cpp22
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp2
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp140
-rw-r--r--indra/newview/lldrawpoolpbropaque.h63
-rw-r--r--indra/newview/lldrawpoolsky.cpp5
-rw-r--r--indra/newview/lldrawpoolterrain.cpp17
-rw-r--r--indra/newview/lldrawpoolwater.cpp72
-rw-r--r--indra/newview/lldrawpoolwater.h30
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp2
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llenvironment.cpp25
-rw-r--r--indra/newview/llface.cpp237
-rw-r--r--indra/newview/llface.h4
-rw-r--r--indra/newview/llfasttimerview.cpp14
-rw-r--r--indra/newview/llfavoritesbar.cpp85
-rw-r--r--indra/newview/llfavoritesbar.h6
-rw-r--r--indra/newview/llfeaturemanager.cpp52
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp103
-rw-r--r--indra/newview/llfetchedgltfmaterial.h57
-rw-r--r--indra/newview/llfilepicker.cpp64
-rw-r--r--indra/newview/llfilepicker.h12
-rw-r--r--indra/newview/llflexibleobject.cpp8
-rw-r--r--indra/newview/llfloater360capture.cpp7
-rw-r--r--indra/newview/llfloater360capture.h1
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp4
-rw-r--r--indra/newview/llfloateravatarpicker.cpp3
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp1
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp10
-rw-r--r--indra/newview/llfloaterchatvoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterclassified.cpp71
-rw-r--r--indra/newview/llfloaterclassified.h (renamed from indra/newview/llpanelme.h)45
-rw-r--r--indra/newview/llfloatercolorpicker.cpp24
-rw-r--r--indra/newview/llfloatercolorpicker.h5
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp129
-rw-r--r--indra/newview/llfloatercreatelandmark.h3
-rw-r--r--indra/newview/llfloaterdisplayname.cpp200
-rw-r--r--indra/newview/llfloaterdisplayname.h (renamed from indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl)21
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp3
-rw-r--r--indra/newview/llfloaterevent.cpp9
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp5
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloaterhoverheight.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp19
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp7
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp14
-rw-r--r--indra/newview/llfloaterjoystick.cpp7
-rw-r--r--indra/newview/llfloaterland.cpp10
-rw-r--r--indra/newview/llfloaterland.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp148
-rw-r--r--indra/newview/llfloatermap.h1
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp20
-rw-r--r--indra/newview/llfloatermediasettings.cpp12
-rw-r--r--indra/newview/llfloatermediasettings.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp45
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp1
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterperms.cpp1
-rw-r--r--indra/newview/llfloaterpreference.cpp246
-rw-r--r--indra/newview/llfloaterpreference.h6
-rw-r--r--indra/newview/llfloaterprofile.cpp170
-rw-r--r--indra/newview/llfloaterprofile.h66
-rw-r--r--indra/newview/llfloaterprofiletexture.cpp223
-rw-r--r--indra/newview/llfloaterprofiletexture.h81
-rw-r--r--indra/newview/llfloaterregioninfo.cpp15
-rw-r--r--indra/newview/llfloaterreporter.cpp55
-rw-r--r--indra/newview/llfloaterreporter.h6
-rw-r--r--indra/newview/llfloatersearch.cpp61
-rw-r--r--indra/newview/llfloatersearch.h4
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp2
-rw-r--r--indra/newview/llfloatertools.cpp945
-rw-r--r--indra/newview/llfloatertools.h20
-rw-r--r--indra/newview/llfloateruipreview.cpp4
-rw-r--r--indra/newview/llfloaterurlentry.cpp10
-rw-r--r--indra/newview/llfloatervoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterwebprofile.cpp81
-rw-r--r--indra/newview/llfloaterwebprofile.h59
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.cpp110
-rw-r--r--indra/newview/llfloaterworldmap.h9
-rw-r--r--indra/newview/llfriendcard.cpp57
-rw-r--r--indra/newview/llfriendcard.h1
-rw-r--r--indra/newview/llgesturemgr.h2
-rw-r--r--indra/newview/llglsandbox.cpp28
-rw-r--r--indra/newview/llgltfmateriallist.cpp298
-rw-r--r--indra/newview/llgltfmateriallist.h70
-rw-r--r--indra/newview/llgroupactions.cpp2
-rw-r--r--indra/newview/llgrouplist.cpp309
-rw-r--r--indra/newview/llgrouplist.h30
-rw-r--r--indra/newview/llgroupmgr.cpp4
-rw-r--r--indra/newview/llhudeffectlookat.cpp2
-rw-r--r--indra/newview/llhudeffectpointat.cpp2
-rw-r--r--indra/newview/llhudicon.cpp54
-rw-r--r--indra/newview/llhudicon.h5
-rw-r--r--indra/newview/llhudnametag.cpp2
-rw-r--r--indra/newview/llhudobject.cpp8
-rw-r--r--indra/newview/llhudtext.cpp4
-rw-r--r--indra/newview/llimview.cpp82
-rw-r--r--indra/newview/llimview.h5
-rw-r--r--indra/newview/llinspect.cpp16
-rw-r--r--indra/newview/llinspect.h2
-rw-r--r--indra/newview/llinspectavatar.cpp15
-rw-r--r--indra/newview/llinspectgroup.cpp13
-rw-r--r--indra/newview/llinspectobject.cpp57
-rw-r--r--indra/newview/llinspectremoteobject.cpp12
-rw-r--r--indra/newview/llinspecttoast.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp127
-rw-r--r--indra/newview/llinventorybridge.h11
-rw-r--r--indra/newview/llinventoryfilter.cpp12
-rw-r--r--indra/newview/llinventoryfunctions.cpp155
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/llinventoryicon.cpp5
-rw-r--r--indra/newview/llinventorylistitem.cpp32
-rw-r--r--indra/newview/llinventorymodel.cpp168
-rw-r--r--indra/newview/llinventorymodel.h30
-rw-r--r--indra/newview/llinventorypanel.cpp67
-rw-r--r--indra/newview/llinventorypanel.h7
-rw-r--r--indra/newview/lllegacyatmospherics.cpp20
-rw-r--r--indra/newview/lllocalbitmaps.cpp98
-rw-r--r--indra/newview/lllocalbitmaps.h5
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp628
-rw-r--r--indra/newview/lllocalgltfmaterials.h129
-rw-r--r--indra/newview/lllocationinputctrl.h2
-rw-r--r--indra/newview/lllogininstance.cpp2
-rw-r--r--indra/newview/llmaniprotate.cpp2
-rw-r--r--indra/newview/llmanipscale.cpp2
-rw-r--r--indra/newview/llmaniptranslate.cpp22
-rw-r--r--indra/newview/llmarketplacefunctions.cpp43
-rw-r--r--indra/newview/llmarketplacefunctions.h3
-rw-r--r--indra/newview/llmaterialeditor.cpp2616
-rw-r--r--indra/newview/llmaterialeditor.h291
-rw-r--r--indra/newview/llmediadataclient.cpp3
-rw-r--r--indra/newview/llmeshrepository.cpp42
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp383
-rw-r--r--indra/newview/llmodelpreview.h31
-rw-r--r--indra/newview/llmutelist.cpp2
-rw-r--r--indra/newview/llnamelistctrl.cpp19
-rw-r--r--indra/newview/llnamelistctrl.h1
-rw-r--r--indra/newview/llnavigationbar.cpp11
-rwxr-xr-xindra/newview/llnavigationbar.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp602
-rw-r--r--indra/newview/llnetmap.h54
-rw-r--r--indra/newview/lloutfitgallery.cpp3
-rw-r--r--indra/newview/llpanelavatar.cpp224
-rw-r--r--indra/newview/llpanelavatar.h183
-rw-r--r--indra/newview/llpanelblockedlist.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp625
-rw-r--r--indra/newview/llpanelclassified.h134
-rw-r--r--indra/newview/llpaneleditsky.cpp15
-rw-r--r--indra/newview/llpaneleditsky.h1
-rw-r--r--indra/newview/llpaneleditwearable.cpp4
-rw-r--r--indra/newview/llpanelexperiences.h1
-rw-r--r--indra/newview/llpanelface.cpp2371
-rw-r--r--indra/newview/llpanelface.h66
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp4
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp4
-rw-r--r--indra/newview/llpanellandaudio.cpp9
-rw-r--r--indra/newview/llpanellandaudio.h1
-rw-r--r--indra/newview/llpanellandmarks.cpp52
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanellogin.cpp147
-rw-r--r--indra/newview/llpanellogin.h1
-rw-r--r--indra/newview/llpanelloginlistener.cpp2
-rw-r--r--indra/newview/llpanelmaininventory.cpp9
-rw-r--r--indra/newview/llpanelme.cpp67
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp6
-rw-r--r--indra/newview/llpanelobject.cpp342
-rw-r--r--indra/newview/llpanelobject.h27
-rw-r--r--indra/newview/llpanelobjectinventory.cpp74
-rw-r--r--indra/newview/llpanelpick.cpp620
-rw-r--r--indra/newview/llpanelpick.h264
-rw-r--r--indra/newview/llpanelpicks.cpp1484
-rw-r--r--indra/newview/llpanelpicks.h315
-rw-r--r--indra/newview/llpanelplaceinfo.cpp12
-rw-r--r--indra/newview/llpanelplaceinfo.h3
-rw-r--r--indra/newview/llpanelplaces.cpp42
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelprofile.cpp2654
-rw-r--r--indra/newview/llpanelprofile.h411
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp1513
-rw-r--r--indra/newview/llpanelprofileclassifieds.h340
-rw-r--r--indra/newview/llpanelprofilepicks.cpp883
-rw-r--r--indra/newview/llpanelprofilepicks.h248
-rw-r--r--indra/newview/llpanelvolume.cpp419
-rw-r--r--indra/newview/llpanelvolume.h16
-rw-r--r--indra/newview/llparticipantlist.cpp170
-rw-r--r--indra/newview/llparticipantlist.h4
-rw-r--r--indra/newview/llpatchvertexarray.cpp2
-rw-r--r--indra/newview/llpathfindingmanager.cpp16
-rw-r--r--indra/newview/llpathfindingmanager.h3
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp12
-rw-r--r--indra/newview/llpersistentnotificationstorage.h1
-rw-r--r--indra/newview/llphysicsshapebuilderutil.cpp13
-rw-r--r--indra/newview/llphysicsshapebuilderutil.h1
-rw-r--r--indra/newview/llplacesinventorypanel.h2
-rw-r--r--indra/newview/llpresetsmanager.cpp2
-rw-r--r--indra/newview/llpreview.h2
-rw-r--r--indra/newview/llpreviewgesture.cpp6
-rw-r--r--indra/newview/llpreviewnotecard.cpp5
-rw-r--r--indra/newview/llpreviewscript.cpp9
-rw-r--r--indra/newview/llpreviewtexture.cpp17
-rw-r--r--indra/newview/llpreviewtexture.h2
-rw-r--r--indra/newview/llrecentpeople.cpp37
-rw-r--r--indra/newview/llrecentpeople.h13
-rw-r--r--indra/newview/llreflectionmap.cpp274
-rw-r--r--indra/newview/llreflectionmap.h102
-rw-r--r--indra/newview/llreflectionmapmanager.cpp920
-rw-r--r--indra/newview/llreflectionmapmanager.h163
-rw-r--r--indra/newview/llremoteparcelrequest.cpp7
-rw-r--r--indra/newview/llscenemonitor.cpp8
-rw-r--r--indra/newview/llsceneview.cpp10
-rw-r--r--indra/newview/llsearchableui.h12
-rw-r--r--indra/newview/llselectmgr.cpp418
-rw-r--r--indra/newview/llselectmgr.h29
-rw-r--r--indra/newview/llsettingsvo.cpp71
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp7
-rw-r--r--indra/newview/llsidepaneltaskinfo.h2
-rw-r--r--indra/newview/llspatialpartition.cpp131
-rw-r--r--indra/newview/llspatialpartition.h32
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llspeakers.h8
-rw-r--r--indra/newview/llsprite.cpp2
-rw-r--r--indra/newview/llstartup.cpp85
-rw-r--r--indra/newview/llsurface.cpp7
-rw-r--r--indra/newview/lltexturecache.cpp3
-rw-r--r--indra/newview/lltexturectrl.cpp398
-rw-r--r--indra/newview/lltexturectrl.h40
-rw-r--r--indra/newview/lltexturefetch.cpp626
-rw-r--r--indra/newview/lltexturefetch.h24
-rw-r--r--indra/newview/lltextureview.cpp1
-rw-r--r--indra/newview/lltinygltfhelper.cpp183
-rw-r--r--indra/newview/lltinygltfhelper.h54
-rw-r--r--indra/newview/lltoastalertpanel.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp116
-rw-r--r--indra/newview/lltooldraganddrop.h15
-rw-r--r--indra/newview/lltoolpie.cpp3
-rw-r--r--indra/newview/lltoolplacer.cpp2
-rw-r--r--indra/newview/lltoolselect.cpp9
-rw-r--r--indra/newview/llviewerassettype.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp123
-rw-r--r--indra/newview/llviewerassetupload.h35
-rw-r--r--indra/newview/llvieweraudio.h2
-rw-r--r--indra/newview/llviewercamera.h13
-rw-r--r--indra/newview/llviewercontrol.cpp354
-rw-r--r--indra/newview/llviewerdisplay.cpp261
-rw-r--r--indra/newview/llviewerdisplayname.cpp226
-rw-r--r--indra/newview/llviewerdisplayname.h55
-rw-r--r--indra/newview/llviewerfloaterreg.cpp15
-rw-r--r--indra/newview/llviewerfoldertype.cpp1
-rw-r--r--indra/newview/llviewerinventory.cpp33
-rw-r--r--indra/newview/llviewermedia.cpp38
-rw-r--r--indra/newview/llviewermedia.h3
-rw-r--r--indra/newview/llviewermenu.cpp460
-rw-r--r--indra/newview/llviewermenu.h5
-rw-r--r--indra/newview/llviewermenufile.cpp59
-rw-r--r--indra/newview/llviewermenufile.h12
-rw-r--r--indra/newview/llviewermessage.cpp34
-rw-r--r--indra/newview/llviewerobject.cpp357
-rw-r--r--indra/newview/llviewerobject.h40
-rw-r--r--indra/newview/llviewerobjectlist.cpp172
-rw-r--r--indra/newview/llviewerobjectlist.h8
-rw-r--r--indra/newview/llvieweroctree.cpp39
-rw-r--r--indra/newview/llvieweroctree.h17
-rw-r--r--indra/newview/llviewerparcelmgr.cpp19
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp80
-rw-r--r--indra/newview/llviewerparceloverlay.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp152
-rw-r--r--indra/newview/llviewerregion.h24
-rw-r--r--indra/newview/llviewershadermgr.cpp1252
-rw-r--r--indra/newview/llviewershadermgr.h24
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewertexteditor.cpp26
-rw-r--r--indra/newview/llviewertexteditor.h1
-rw-r--r--indra/newview/llviewertexture.cpp33
-rw-r--r--indra/newview/llviewertexture.h4
-rw-r--r--indra/newview/llviewertexturelist.cpp200
-rw-r--r--indra/newview/llviewertexturelist.h17
-rw-r--r--indra/newview/llviewerwindow.cpp260
-rw-r--r--indra/newview/llviewerwindow.h19
-rw-r--r--indra/newview/llvoavatar.cpp107
-rw-r--r--indra/newview/llvoavatar.h12
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvocache.cpp52
-rw-r--r--indra/newview/llvograss.cpp8
-rw-r--r--indra/newview/llvograss.h1
-rw-r--r--indra/newview/llvoground.cpp2
-rw-r--r--indra/newview/llvoicechannel.cpp23
-rw-r--r--indra/newview/llvoiceclient.cpp6
-rw-r--r--indra/newview/llvoiceclient.h1
-rw-r--r--indra/newview/llvoicevisualizer.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp56
-rw-r--r--indra/newview/llvoicevivox.h2
-rw-r--r--indra/newview/llvopartgroup.cpp12
-rw-r--r--indra/newview/llvopartgroup.h1
-rw-r--r--indra/newview/llvosky.cpp14
-rw-r--r--indra/newview/llvosurfacepatch.cpp6
-rw-r--r--indra/newview/llvosurfacepatch.h1
-rw-r--r--indra/newview/llvotree.cpp6
-rw-r--r--indra/newview/llvotree.h1
-rw-r--r--indra/newview/llvovolume.cpp529
-rw-r--r--indra/newview/llvovolume.h184
-rw-r--r--indra/newview/llvowater.cpp4
-rw-r--r--indra/newview/llvowlsky.cpp4
-rw-r--r--indra/newview/llwebprofile.cpp2
-rw-r--r--indra/newview/llworld.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp277
-rw-r--r--indra/newview/llworldmapview.h43
-rw-r--r--indra/newview/llxmlrpctransaction.cpp10
-rw-r--r--indra/newview/pipeline.cpp2067
-rw-r--r--indra/newview/pipeline.h130
-rw-r--r--indra/newview/skins/default/colors.xml28
-rw-r--r--indra/newview/skins/default/textures/default_irradiance.pngbin0 -> 48853 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Off.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Press.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.pngbin0 -> 218 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.pngbin0 -> 217 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.pngbin0 -> 215 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/CopyBright.pngbin0 -> 519 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Material.pngbin0 -> 684 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Offline.pngbin0 -> 208 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Online.pngbin0 -> 189 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.pngbin0 -> 1608 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.pngbin0 -> 1287 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.pngbin0 -> 1356 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.pngbin0 -> 1137 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.pngbin0 -> 1312 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.pngbin0 -> 1150 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/avaline_default_icon.jpgbin3951 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.pngbin0 -> 507 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.pngbin0 -> 639 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.pngbin0 -> 485 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.pngbin0 -> 609 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_collapse_icon.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_expand_icon.pngbin0 -> 284 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml29
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image.jpgbin0 -> 104529 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_left.pngbin271413 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_right.pngbin366068 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/da/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/da/panel_region_texture.xml4
-rw-r--r--indra/newview/skins/default/xui/da/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/de/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/de/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/de/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml25
-rw-r--r--indra/newview/skins/default/xui/en/floater_build_options.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_classified.xml (renamed from indra/newview/skins/default/xui/en/floater_picks.xml)13
-rw-r--r--indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml48
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_display_name.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml43
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml532
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_environments.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml68
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml253
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml208
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_permissions.xml76
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_texture.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml16
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml250
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml93
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/main_view.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml23
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_self.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_color.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_features.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_light.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_object.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_size.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml554
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml120
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_other.xml171
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_self.xml85
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_agent.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml93
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml202
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml37
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml354
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml239
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml472
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item_short.xml110
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml71
-rw-r--r--indra/newview/skins/default/xui/en/panel_me.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml227
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml30
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_uploads.xml25
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classified.xml830
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classifieds.xml142
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml103
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_notes.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_pick.xml314
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_picks.xml154
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml549
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_web.xml36
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml134
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml42
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/es/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/es/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/fr/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/fr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/fr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/es/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/it/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/it/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_friends.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_photo.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_status.xml10
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/ja/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ja/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_photo.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_status.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_options.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/pl/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/it/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml40
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ru/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/floater_report_abuse.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_classified.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_photo.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_place.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_status.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/tr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/tr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/tr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_photo.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_status.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/zh/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/zh/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml38
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp1
-rwxr-xr-xindra/newview/viewer_manifest.py3
835 files changed, 40903 insertions, 20498 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f13ce85495..374db7fdf8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -56,7 +56,8 @@ include(UnixInstall)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
-include(ZLIB)
+include(VulkanGltf)
+include(ZLIBNG)
include(URIPARSER)
if (NOT HAVOK_TPV)
@@ -187,6 +188,7 @@ set(viewer_SOURCE_FILES
lldrawpoolbump.cpp
lldrawpoolground.cpp
lldrawpoolmaterials.cpp
+ lldrawpoolpbropaque.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -206,6 +208,7 @@ set(viewer_SOURCE_FILES
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
+ llfetchedgltfmaterial.cpp
llfilepicker.cpp
llfilteredwearablelist.cpp
llfirstuse.cpp
@@ -234,12 +237,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
+ llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@@ -295,9 +300,11 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
+ llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
+ llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@@ -329,7 +336,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
- llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@@ -341,6 +347,7 @@ set(viewer_SOURCE_FILES
llgesturemgr.cpp
llgiveinventory.cpp
llglsandbox.cpp
+ llgltfmateriallist.cpp
llgroupactions.cpp
llgroupiconctrl.cpp
llgrouplist.cpp
@@ -390,6 +397,7 @@ set(viewer_SOURCE_FILES
lllistcontextmenu.cpp
lllistview.cpp
lllocalbitmaps.cpp
+ lllocalgltfmaterials.cpp
lllocationhistory.cpp
lllocationinputctrl.cpp
lllogchat.cpp
@@ -402,6 +410,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialeditor.cpp
llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
@@ -475,7 +484,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@@ -485,8 +493,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
- llpanelpick.cpp
- llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@@ -495,6 +501,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
+ llpanelprofileclassifieds.cpp
+ llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@@ -544,6 +552,8 @@ set(viewer_SOURCE_FILES
llproductinforequest.cpp
llprogressview.cpp
llrecentpeople.cpp
+ llreflectionmap.cpp
+ llreflectionmapmanager.cpp
llregioninfomodel.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
@@ -600,6 +610,7 @@ set(viewer_SOURCE_FILES
lltextureinfodetails.cpp
lltexturestats.cpp
lltextureview.cpp
+ lltinygltfhelper.cpp
lltoast.cpp
lltoastalertpanel.cpp
lltoastgroupnotifypanel.cpp
@@ -656,6 +667,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
+ llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -821,6 +833,7 @@ set(viewer_HEADER_FILES
lldrawpoolavatar.h
lldrawpoolbump.h
lldrawpoolmaterials.h
+ lldrawpoolpbropaque.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h
@@ -841,6 +854,7 @@ set(viewer_HEADER_FILES
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
+ llfetchedgltfmaterial.h
llfilepicker.h
llfilteredwearablelist.h
llfirstuse.h
@@ -869,12 +883,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
+ llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@@ -933,9 +949,11 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
+ llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
+ llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@@ -967,7 +985,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
- llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@@ -978,6 +995,7 @@ set(viewer_HEADER_FILES
llgesturelistener.h
llgesturemgr.h
llgiveinventory.h
+ llgltfmateriallist.h
llgroupactions.h
llgroupiconctrl.h
llgrouplist.h
@@ -1026,6 +1044,7 @@ set(viewer_HEADER_FILES
lllistcontextmenu.h
lllistview.h
lllocalbitmaps.h
+ lllocalgltfmaterials.h
lllocationhistory.h
lllocationinputctrl.h
lllogchat.h
@@ -1038,6 +1057,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialeditor.h
llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
@@ -1103,7 +1123,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@@ -1113,8 +1132,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
- llpanelpick.h
- llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@@ -1123,6 +1140,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
+ llpanelprofileclassifieds.h
+ llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@@ -1167,6 +1186,8 @@ set(viewer_HEADER_FILES
llproductinforequest.h
llprogressview.h
llrecentpeople.h
+ llreflectionmap.h
+ llreflectionmapmanager.h
llregioninfomodel.h
llregionposition.h
llremoteparcelrequest.h
@@ -1227,6 +1248,7 @@ set(viewer_HEADER_FILES
lltextureinfodetails.h
lltexturestats.h
lltextureview.h
+ lltinygltfhelper.h
lltoast.h
lltoastalertpanel.h
lltoastgroupnotifypanel.h
@@ -1285,6 +1307,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
+ llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
@@ -1667,18 +1690,23 @@ set_source_files_properties(${viewer_XUI_FILES}
list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES})
+file(GLOB_RECURSE viewer_SHADER_FILES LIST_DIRECTORIES TRUE
+ ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders/*.glsl)
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders PREFIX "Shaders" FILES ${viewer_SHADER_FILES})
+set_source_files_properties(${viewer_SHADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+list(APPEND viewer_SOURCE_FILES ${viewer_SHADER_FILES})
+
+
set(viewer_APPSETTINGS_FILES
app_settings/anim.ini
app_settings/cmd_line.xml
app_settings/commands.xml
app_settings/grass.xml
- app_settings/high_graphics.xml
app_settings/ignorable_dialogs.xml
app_settings/key_bindings.xml
app_settings/keywords_lsl_default.xml
app_settings/logcontrol.xml
- app_settings/low_graphics.xml
- app_settings/mid_graphics.xml
app_settings/settings.xml
app_settings/settings_crash_behavior.xml
app_settings/settings_files.xml
@@ -1686,7 +1714,6 @@ set(viewer_APPSETTINGS_FILES
app_settings/std_bump.ini
app_settings/toolbars.xml
app_settings/trees.xml
- app_settings/ultra_graphics.xml
app_settings/viewerart.xml
${CMAKE_SOURCE_DIR}/../etc/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
@@ -1841,10 +1868,6 @@ if (WINDOWS)
winmm_shim
)
- if (NOT USE_BUGSPLAT)
- LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
- endif (NOT USE_BUGSPLAT)
-
if (ADDRESS_SIZE EQUAL 64)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
@@ -2009,14 +2032,14 @@ endif (WINDOWS)
#
# We generally want the newest version of the library to provide all symbol
# resolution. To that end, when using static archives, the *_PRELOAD_ARCHIVES
-# variables, PNG_PRELOAD_ARCHIVES and ZLIB_PRELOAD_ARCHIVES, get the archives
+# variables, PNG_PRELOAD_ARCHIVES and ZLIBNG_PRELOAD_ARCHIVES, get the archives
# dumped into the target binary and runtime lookup will find the most
# modern version.
target_link_libraries(${VIEWER_BINARY_NAME}
${LEGACY_STDIO_LIBS}
${PNG_PRELOAD_ARCHIVES}
- ${ZLIB_PRELOAD_ARCHIVES}
+ ${ZLIBNG_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${LLAUDIO_LIBRARIES}
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 09a7391e4e..66ce77b7ea 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.1
+7.0.0
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index dd2b656ce3..e16a5c7e76 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -55,7 +55,7 @@
<key>debugsession</key>
<map>
<key>desc</key>
- <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string>
+ <string>Run as if RenderDebugGLSession is TRUE, but log errors until end of session.</string>
<key>map-to</key>
<string>DebugSession</string>
</map>
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 3dfe3f6634..2644f5f449 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="picks"
- is_running_function="Floater.IsOpen"
- is_running_parameters="picks"
+ execute_function="Avatar.TogglePicks"
+ is_running_function="Avatar.IsPicksTabOpen"
/>
<command name="places"
available_in_toybox="true"
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
deleted file mode 100644
index f64937f443..0000000000
--- a/indra/newview/app_settings/high_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.9"/>
- <!--Short Range-->
- <RenderFarClip value="128"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="2"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="20"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1250.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--Sun Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml
index 55babc88bc..8d5349550f 100644
--- a/indra/newview/app_settings/key_bindings.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -85,7 +85,6 @@
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
- <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</third_person>
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 482012cdd6..2a26cb9a43 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -73,6 +73,7 @@
<string>Avatar</string>
<string>Voice</string>
-->
+ <string>Capabilities</string>
</array>
</map>
</array>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
deleted file mode 100644
index b31a040d67..0000000000
--- a/indra/newview/app_settings/low_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.0"/>
- <!--Short Range-->
- <RenderFarClip value="64"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="0.5"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="1024"/>
- <!--bump okay-->
- <RenderObjectBump value="FALSE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="0"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="12"/>
- <RenderAvatarMaxComplexity value="80000"/>
- <RenderAutoMuteSurfaceAreaLimit value="750.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
deleted file mode 100644
index 9c2c17fc60..0000000000
--- a/indra/newview/app_settings/mid_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.75"/>
- <!--Short Range-->
- <RenderFarClip value="96"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="2048"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="18"/>
- <RenderAvatarMaxComplexity value="150000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1000.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bc4945eca5..3f9a91e38f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -544,17 +544,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AvalinePhoneSeparator</key>
- <map>
- <key>Comment</key>
- <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>-</string>
- </map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@@ -1252,6 +1241,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BulkChangeIncludeMaterials</key>
+ <map>
+ <key>Comment</key>
+ <string>Bulk permission changes affect materials</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>BulkChangeEveryoneCopy</key>
<map>
<key>Comment</key>
@@ -1371,7 +1371,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>20.0</real>
+ <real>40.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@@ -3847,7 +3847,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://events.secondlife.com/viewer/embed/event/</string>
+ <string>http://events.[GRID]/viewer/embed/event/[EVENT_ID]</string>
</map>
<key>FastCacheFetchEnabled</key>
<map>
@@ -4758,7 +4758,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+ <string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@@ -5806,6 +5806,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DiskCacheVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Version number of disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LocalFileSystemBrowsingEnabled</key>
<map>
<key>Comment</key>
@@ -6808,6 +6819,9 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <!-- *HACK: On first run, set this to 0 for new users,
+ otherwise the default is 1 to maintain consistent experience
+ for existing users. Hardcoded in llnetmap.cpp -->
<integer>1</integer>
</map>
<key>MiniMapScale</key>
@@ -6821,6 +6835,17 @@
<key>Value</key>
<real>128.0</real>
</map>
+ <key>MiniMapShowPropertyLines</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show parcel borders on the MiniMap.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>MouseSensitivity</key>
<map>
<key>Comment</key>
@@ -7099,13 +7124,13 @@
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
- <string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string>
+ <string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>300</integer>
+ <integer>64</integer>
</map>
<key>NoPreload</key>
<map>
@@ -8635,6 +8660,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UpdateRememberPasswordSetting</key>
+ <map>
+ <key>Comment</key>
+ <string>Save 'rememeber password' setting for current user.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>OctreeMaxNodeCapacity</key>
<map>
<key>Comment</key>
@@ -8784,13 +8820,13 @@
<key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
- <string>Controls if avatars use wavy cloth</string>
+ <string>DEPRECATED - only false supported - Controls if avatars use wavy cloth</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>RenderComplexityColorMin</key>
<map>
@@ -9141,10 +9177,10 @@
<key>Value</key>
<real>0.5</real>
</map>
- <key>RenderDebugGL</key>
+ <key>RenderDebugGLSession</key>
<map>
<key>Comment</key>
- <string>Enable strict GL debugging.</string>
+ <string>Enable strict GL debugging on the start of next session.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9599,16 +9635,28 @@
<real>368.0</real>
</map>
+ <key>RenderPBR</key>
+ <map>
+ <key>Comment</key>
+ <string>DEPRECATED - only true supported - Use PBR rendering pipeline (Physically Based Rendering).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+
<key>RenderDeferred</key>
<map>
<key>Comment</key>
- <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
+ <string>DEPRECATED (only true supported) - Use deferred rendering pipeline (Advanced Lighting Model).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderDeferredSun</key>
@@ -9823,7 +9871,7 @@
<key>RenderFogRatio</key>
<map>
<key>Comment</key>
- <string>Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
+ <string>DEPRECATED - Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9834,7 +9882,7 @@
<key>RenderGamma</key>
<map>
<key>Comment</key>
- <string>Sets gamma exponent for renderer</string>
+ <string>DEPRECATED - Sets gamma exponent for renderer</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9867,7 +9915,7 @@
<key>RenderGLContextCoreProfile</key>
<map>
<key>Comment</key>
- <string>Don't use a compatibility profile OpenGL context. Requires restart. Basic shaders MUST be enabled.</string>
+ <string>Don't use a compatibility profile OpenGL context. Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10227,7 +10275,7 @@
<key>RenderObjectBump</key>
<map>
<key>Comment</key>
- <string>Show bumpmapping on primitives</string>
+ <string>DEPRECATED (only TRUE supported) Show bumpmapping on primitives</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10249,7 +10297,7 @@
<key>RenderReflectionDetail</key>
<map>
<key>Comment</key>
- <string>Detail of reflection render pass.</string>
+ <string>DEPRECATED -- use RenderTransparentWater and RenderReflectionProbeDetail -- Detail of reflection render pass.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10268,8 +10316,64 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>RenderReflectionProbeDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail of reflections. (-1 - Disabled, 0 - Static Only, 1 - Static + Dynamic, 2 - Realtime)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderReflectionProbeCount</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of reflection probes (maximum is 256, requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>256</integer>
+ </map>
- <key>RenderReflectionRes</key>
+ <key>RenderReflectionProbeDrawDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera far clip to use when updating reflection probes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>64</real>
+ </map>
+ <key>RenderReflectionProbeAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount reflection probes contribute to ambient light.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+ <key>RenderReflectionProbeTextureHackID</key>
+ <map>
+ <key>Comment</key>
+ <string>HACK -- Any object with a diffuse texture with this ID will be treated as a user override reflection probe. (default is "Violet Info Hub" photo from Library)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>6b186931-05da-eafa-a3ed-a012a33bbfb6</string>
+ </map>
+
+ <key>RenderReflectionRes</key>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
@@ -10660,18 +10764,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderUseTransformFeedback</key>
- <map>
- <key>Comment</key>
- <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
-
<key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
@@ -11000,7 +11092,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>1024</integer>
+ <integer>2048</integer>
</map>
<key>SceneLoadLowMemoryBound</key>
<map>
@@ -11134,6 +11226,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SelectInvisibleObjects</key>
+ <map>
+ <key>Comment</key>
+ <string>Select invisible objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>SelectOwnedOnly</key>
<map>
<key>Comment</key>
@@ -14735,7 +14838,7 @@
<key>WindLightUseAtmosShaders</key>
<map>
<key>Comment</key>
- <string>Whether to enable or disable WindLight atmospheric shaders.</string>
+ <string>DEPRECATED (only true supported) - Whether to enable or disable WindLight atmospheric shaders.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -15607,6 +15710,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>AllowSelectAvatar</key>
+ <map>
+ <key>Comment</key>
+ <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>WebProfileFloaterRect</key>
<map>
<key>Comment</key>
@@ -16013,6 +16127,61 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MaterialsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created GLTF material</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF materials are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DefaultUploadPermissionsConverted</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 537744b44c..eb3528b9b7 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -370,6 +370,17 @@
<key>Value</key>
<string></string>
</map>
+ <key>PBRUploadFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>All pbr uploads will be stored in this directory (UUID)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
<key>TextureUploadFolder</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 02b2daf0ac..f4ec1ec532 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -25,305 +25,11 @@
//class1/deferred/alphaF.glsl
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
-
-#define INDEXED 1
-#define NON_INDEXED 2
-#define NON_INDEXED_NO_COLOR 3
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform mat3 env_mat;
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-
-#ifdef USE_DIFFUSE_TEX
-uniform sampler2D diffuseMap;
-#endif
-
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
-
-#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color; //vertex color should be treated as sRGB
-#endif
-
-#ifdef HAS_ALPHA_MASK
-uniform float minimum_alpha;
-#endif
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform int sun_up_factor;
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 srgb_to_linear(vec3 c);
-vec3 linear_to_srgb(vec3 c);
-
-vec2 encode_normal (vec3 n);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive, bool use_ao);
-
-#ifdef HAS_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-#endif
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
-{
- // SL-14895 inverted attenuation work-around
- // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
- // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
- // to recover the `adjusted_radius` value previously being sent as la.
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
- // Yes, it makes me want to cry as well. DJH
-
- vec3 col = vec3(0);
-
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float dist = length(lv);
- float da = 1.0;
- /*if (dist > inverted_la)
- {
- return col;
- }
-
- clip to projector bounds
- vec4 proj_tc = proj_mat * lp;
-
- if (proj_tc.z < 0
- || proj_tc.z > 1
- || proj_tc.x < 0
- || proj_tc.x > 1
- || proj_tc.y < 0
- || proj_tc.y > 1)
- {
- return col;
- }*/
-
- if (dist > 0.0 && inverted_la > 0.0)
- {
- dist /= inverted_la;
-
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0f;
-
- if (dist_atten <= 0.0)
- {
- return col;
- }
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= dot(n, lv);
- da = max(0.0, da);
-
- float lit = 0.0f;
-
- float amb_da = 0.0;//ambiance;
- if (da > 0)
- {
- lit = max(da * dist_atten,0.0);
- col = lit * light_col * diffuse;
- amb_da += (da*0.5+0.5) * ambiance;
- }
- amb_da += (da*da*0.5 + 0.5) * ambiance;
- amb_da *= dist_atten;
- amb_da = min(amb_da, 1.0f - lit);
-
- // SL-10969 ... need to work out why this blows out in many setups...
- //col.rgb += amb_da * light_col * diffuse;
-
- // no spec for alpha shader...
- }
- col = max(col, vec3(0));
- return col;
-}
-
-void main()
+void main()
{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- vec4 pos = vec4(vary_position, 1.0);
- vec3 norm = vary_norm;
-
- float shadow = 1.0f;
-
-#ifdef HAS_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
-#endif
-
-#ifdef USE_DIFFUSE_TEX
- vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
-#endif
-
-#ifdef USE_INDEXED_TEX
- vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
-#endif
-
- vec4 diffuse_srgb = diffuse_tap;
-
-#ifdef FOR_IMPOSTOR
- vec4 color;
- color.rgb = diffuse_srgb.rgb;
- color.a = 1.0;
-
- float final_alpha = diffuse_srgb.a * vertex_color.a;
- diffuse_srgb.rgb *= vertex_color.rgb;
-
- // Insure we don't pollute depth with invis pixels in impostor rendering
- //
- if (final_alpha < minimum_alpha)
- {
- discard;
- }
-
- color.rgb = diffuse_srgb.rgb;
- color.a = final_alpha;
-
-#else // FOR_IMPOSTOR
-
- vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
-
- float final_alpha = diffuse_linear.a;
-
-#ifdef USE_VERTEX_COLOR
- final_alpha *= vertex_color.a;
-
- if (final_alpha < minimum_alpha)
- { // TODO: figure out how to get invisible faces out of
- // render batches without breaking glow
- discard;
- }
-
- diffuse_srgb.rgb *= vertex_color.rgb;
- diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
-#endif // USE_VERTEX_COLOR
-
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-
- vec2 abnormal = encode_normal(norm.xyz);
-
- float da = dot(norm.xyz, light_dir.xyz);
- da = clamp(da, -1.0, 1.0);
- da = pow(da, 1.0/1.3);
-
- float final_da = da;
- final_da = clamp(final_da, 0.0f, 1.0f);
-
- vec4 color = vec4(0.0);
-
- color.a = final_alpha;
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(final_da, shadow) * sunlit;
-
-#if !defined(AMBIENT_KILL)
- color.rgb = amblit;
- color.rgb *= ambient;
-#endif // !defined(AMBIENT_KILL)
-
-vec3 post_ambient = color.rgb;
-
-#if !defined(SUNLIGHT_KILL)
- color.rgb += sun_contrib;
-#endif // !defined(SUNLIGHT_KILL)
-
-vec3 post_sunlight = color.rgb;
-
- color.rgb *= diffuse_srgb.rgb;
-
-vec3 post_diffuse = color.rgb;
-
- color.rgb = atmosFragLighting(color.rgb, additive, atten);
-
-vec3 post_atmo = color.rgb;
-
- vec4 light = vec4(0,0,0,0);
-
- color.rgb = scaleSoftClipFrag(color.rgb);
-
- //convert to linear before applying local lights
- color.rgb = srgb_to_linear(color.rgb);
-
- #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- // sum local light contrib in linear colorspace
-#if !defined(LOCAL_LIGHT_KILL)
- color.rgb += light.rgb;
-#endif // !defined(LOCAL_LIGHT_KILL)
- // back to sRGB as we're going directly to the final RT post-deferred gamma correction
- color.rgb = linear_to_srgb(color.rgb);
-
-//color.rgb = amblit;
-//color.rgb = vec3(ambient);
-//color.rgb = sunlit;
-//color.rgb = vec3(final_da);
-//color.rgb = post_ambient;
-//color.rgb = post_sunlight;
-//color.rgb = sun_contrib;
-//color.rgb = diffuse_srgb.rgb;
-//color.rgb = post_diffuse;
-//color.rgb = post_atmo;
-
-#ifdef WATER_FOG
- color = applyWaterFogView(pos.xyz, color);
-#endif // WATER_FOG
-
-#endif // #else // FOR_IMPOSTOR
-
- frag_color = color;
+ frag_color = vec4(1,0,1,0.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
index c64b6ba240..c2372fcbc0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
@@ -58,7 +58,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
index b54c580ce9..d0a049d372 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
@@ -35,7 +35,7 @@ uniform sampler2D diffuseMap;
VARYING float pos_w;
VARYING float target_pos_x;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
index 31b93dc36a..a7bf4d7780 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file attachmentShadowV.glsl
+ * @file attachmentAlphaShadowV.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -35,7 +35,7 @@ ATTRIBUTE vec2 texcoord0;
mat4 getObjectSkinnedTransform();
void passTextureIndex();
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING vec2 vary_texcoord0;
@@ -61,7 +61,7 @@ void main()
vertex_color = diffuse_color;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
post_pos = p;
gl_Position = p;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
index b8ce54bcb1..f231213ac8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file treeShadowF.glsl
+ * @file avatarAlphaMaskShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,7 +32,7 @@ out vec4 frag_color;
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -59,7 +59,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index 1b16e4eb09..0e66c722b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -33,7 +33,7 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index 1c5b142ebd..40ac7b1f95 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file avatarShadowV.glsl
+ * @file avatarAlphaShadowV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -34,7 +34,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float pos_w;
@@ -66,7 +66,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 60d83cc623..22b3bd1463 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -52,6 +52,6 @@ void main()
frag_data[0] = vec4(diff.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 596d0274af..fa3634f3b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -69,36 +69,47 @@ void main()
tc_mod *= 2.0;
tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
- for (int i = 1; i < 4; i++)
+ // TODO: move this to kern instead of building kernel per pixel
+ vec3 k[7];
+ k[0] = kern[0];
+ k[2] = kern[1];
+ k[4] = kern[2];
+ k[6] = kern[3];
+
+ k[1] = (k[0]+k[2])*0.5f;
+ k[3] = (k[2]+k[4])*0.5f;
+ k[5] = (k[4]+k[6])*0.5f;
+
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc + kern[i].z*dlt;
+ vec2 samptc = tc + k[i].z*dlt*2.0;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture2DRect(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
- for (int i = 1; i < 4; i++)
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc - kern[i].z*dlt;
+ vec2 samptc = tc - k[i].z*dlt*2.0;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture2DRect(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
col /= defined_weight.xyxx;
- col.y *= col.y;
+ //col.y *= max(col.y, 0.75);
frag_color = col;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index b5677a07ee..749ec3a6ac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -64,5 +64,5 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
deleted file mode 100644
index 0157d166e0..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale >= 0.0001)
- {
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index ae1ac5de7f..788ce4a47b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -34,15 +34,15 @@ out vec4 frag_data[3];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
+uniform vec3 cloud_pos_density1;
+uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
@@ -69,8 +69,8 @@ void main()
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ vec3 cloudColorSun = vary_CloudColorSun;
+ vec3 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
@@ -115,7 +115,7 @@ void main()
alpha2 = 1. - alpha2 * alpha2;
// Combine
- vec4 color;
+ vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
color.rgb= max(vec3(0), color.rgb);
color.rgb *= 2.0;
@@ -124,7 +124,7 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, alpha1);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,0,1);
+ frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.99995f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 8e0a001403..5ca210863e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -33,8 +33,8 @@ ATTRIBUTE vec2 texcoord0;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
VARYING vec2 vary_texcoord0;
@@ -46,13 +46,13 @@ VARYING float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -60,10 +60,10 @@ uniform float cloud_shadow;
uniform float density_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
uniform float cloud_scale;
@@ -114,17 +114,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
+ vec3 sunlight = sunlight_color;
+ vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -155,14 +155,14 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
+ vec3 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow);
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
@@ -178,7 +178,7 @@ void main()
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= combined_haze;
vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index e27bbce094..1a96ee0736 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -23,12 +23,118 @@
* $/LicenseInfo$
*/
+
+/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+*/
+
uniform sampler2DRect normalMap;
uniform sampler2DRect depthMap;
+uniform sampler2D projectionMap; // rgba
+uniform sampler2D brdfLut;
+
+// projected lighted params
+uniform mat4 proj_mat; //screen space to light space projector
+uniform vec3 proj_n; // projector normal
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform float proj_focus; // distance from plane to begin blurring
+uniform float proj_lod ; // (number of mips in proj map)
+uniform float proj_range; // range between near clip and far clip plane of projection
+uniform float proj_ambiance;
+
+// light params
+uniform vec3 color; // light_color
+uniform float size; // light_size
uniform mat4 inv_proj;
uniform vec2 screen_res;
+const float M_PI = 3.14159265;
+const float ONE_OVER_PI = 0.3183098861;
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 light);
+
+float calcLegacyDistanceAttenuation(float distance, float falloff)
+{
+ float dist_atten = 1.0 - clamp((distance + falloff)/(1.0 + falloff), 0.0, 1.0);
+ dist_atten *= dist_atten;
+
+ // Tweak falloff slightly to match pre-EEP attenuation
+ // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
+ dist_atten *= 2.0;
+ return dist_atten;
+}
+
+// In:
+// lv unnormalized surface to light vector
+// n normal of the surface
+// pos unnormalized camera to surface vector
+// Out:
+// l normalized surace to light vector
+// nl diffuse angle
+// nh specular angle
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
+ out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist)
+{
+ l = normalize(lv);
+ h = normalize(l + v);
+ nh = clamp(dot(n, h), 0.0, 1.0);
+ nl = clamp(dot(n, l), 0.0, 1.0);
+ nv = clamp(dot(n, v), 0.0, 1.0);
+ vh = clamp(dot(v, h), 0.0, 1.0);
+
+ lightDist = length(lv);
+}
+
+// In:
+// light_center
+// pos
+// Out:
+// dist
+// l_dist
+// lv
+// proj_tc Projector Textue Coordinates
+bool clipProjectedLightVars(vec3 light_center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc )
+{
+ lv = light_center - pos.xyz;
+ dist = length(lv);
+ bool clipped = (dist >= size);
+ if ( !clipped )
+ {
+ dist /= size;
+
+ l_dist = -dot(lv, proj_n);
+ vec4 projected_point = (proj_mat * vec4(pos.xyz, 1.0));
+ clipped = (projected_point.z < 0.0);
+ projected_point.xyz /= projected_point.w;
+ proj_tc = projected_point;
+ }
+
+ return clipped;
+}
+
vec2 getScreenCoordinate(vec2 screenpos)
{
vec2 sc = screenpos.xy * 2.0;
@@ -39,6 +145,8 @@ vec2 getScreenCoordinate(vec2 screenpos)
return sc - vec2(1.0, 1.0);
}
+// See: https://aras-p.info/texts/CompactNormalStorage.html
+// Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection
vec3 getNorm(vec2 screenpos)
{
vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
@@ -51,12 +159,155 @@ vec3 getNorm(vec2 screenpos)
return n;
}
+vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags)
+{
+ vec2 enc = packedNormalEnvIntensityFlags.xy;
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return normalize(n); // TODO: Is this normalize redundant?
+}
+
+// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w
+// See: C++: addDeferredAttachments(), GLSL: softenLightF
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)
+{
+ vec4 packedNormalEnvIntensityFlags = texture2DRect(normalMap, screenpos.xy);
+ n = getNormalFromPacked( packedNormalEnvIntensityFlags );
+ envIntensity = packedNormalEnvIntensityFlags.z;
+ return packedNormalEnvIntensityFlags;
+}
+
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar)
+{
+ d = d * 2.0 - 1.0;
+ return znear * 2.0 * zfar / (zfar + znear - d * (zfar - znear));
+}
+
float getDepth(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen).r;
return depth;
}
+vec4 getTexture2DLodAmbient(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = tc-vec2(0.5);
+ float d = dot(dist,dist);
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+vec4 getTexture2DLodDiffuse(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// lit This is set by the caller: if (nl > 0.0) { lit = attenuation * nl * noise; }
+// Uses:
+// color Projected spotlight color
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv)
+{
+ vec4 amb_plcol = getTexture2DLodAmbient(projected_uv, proj_lod);
+ vec3 amb_rgb = amb_plcol.rgb * amb_plcol.a;
+
+ amb_da += proj_ambiance;
+ amb_da += (nl*nl*0.5+0.5) * proj_ambiance;
+ amb_da *= attenuation * noise;
+ amb_da = min(amb_da, 1.0-lit);
+
+ return (amb_da * color.rgb * amb_rgb);
+}
+
+// Returns projected light in Linear
+// Uses global spotlight color:
+// color
+// NOTE: projected.a will be pre-multiplied with projected.rgb
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod);
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
+vec4 texture2DLodSpecular(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture2D(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// See: clipProjectedLightVars()
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n )
+{
+ vec3 slit = vec3(0);
+ vec3 ref = reflect(normalize(pos), n);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float l_dist = length(pdelta);
+ float ds = dot(ref, proj_n);
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ if (stc.z > 0.0)
+ {
+ stc /= stc.w;
+ slit = getProjectedLightDiffuseColor( l_dist, stc.xy ); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+ }
+ }
+ return slit; // specular light
+}
+
+vec3 getProjectedLightSpecularColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = getDepth(pos_screen);
@@ -68,12 +319,241 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+// get position given a normalized device coordinate
+vec3 getPositionWithNDC(vec3 ndc)
+{
+ vec4 pos = inv_proj * vec4(ndc, 1.0);
+ return pos.xyz / pos.w;
+}
+
vec4 getPositionWithDepth(vec2 pos_screen, float depth)
{
vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec3 ndc = vec3(sc.x, sc.y, 2.0*depth-1.0);
+ return vec4(getPositionWithNDC(ndc), 1.0);
+}
+
+
+vec2 getScreenXY(vec4 clip)
+{
+ vec4 ndc = clip;
+ ndc.xyz /= clip.w;
+ vec2 screen = vec2( ndc.xy * 0.5 );
+ screen += 0.5;
+ screen *= screen_res;
+ return screen;
+}
+
+// Color utils
+
+vec3 colorize_dot(float x)
+{
+ if (x > 0.0) return vec3( 0, x, 0 );
+ if (x < 0.0) return vec3(-x, 0, 0 );
+ return vec3( 0, 0, 1 );
+}
+
+vec3 hue_to_rgb(float hue)
+{
+ if (hue > 1.0) return vec3(0.5);
+ vec3 rgb = abs(hue * 6. - vec3(3, 2, 4)) * vec3(1, -1, -1) + vec3(-1, 2, 2);
+ return clamp(rgb, 0.0, 1.0);
}
+
+// PBR Utils
+
+vec2 BRDF(float NoV, float roughness)
+{
+ return texture(brdfLut, vec2(NoV, roughness)).rg;
+}
+
+// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRough)
+{
+ // retrieve a scale and bias to F0. See [1], Figure 3
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec3 diffuseLight = irradiance;
+ vec3 specularLight = radiance;
+
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+
+ return (diffuse + specular*0.5) * ao; //reduce by half to place in appropriate color space for atmospherics
+}
+
+// Encapsulate the various inputs used by the various functions in the shading equation
+// We store values in this struct to simplify the integration of alternative implementations
+// of the shading terms, outlined in the Readme.MD Appendix.
+struct PBRInfo
+{
+ float NdotL; // cos angle between normal and light direction
+ float NdotV; // cos angle between normal and view direction
+ float NdotH; // cos angle between normal and half vector
+ float LdotH; // cos angle between light direction and half vector
+ float VdotH; // cos angle between view direction and half vector
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
+ float metalness; // metallic value at the surface
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
+ vec3 reflectance90; // reflectance color at grazing angle
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
+ vec3 diffuseColor; // color contribution from diffuse lighting
+ vec3 specularColor; // color contribution from specular lighting
+};
+
+// Basic Lambertian diffuse
+// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
+// See also [1], Equation 1
+vec3 diffuse(PBRInfo pbrInputs)
+{
+ return pbrInputs.diffuseColor / M_PI;
+}
+
+// The following equation models the Fresnel reflectance term of the spec equation (aka F())
+// Implementation of fresnel from [4], Equation 15
+vec3 specularReflection(PBRInfo pbrInputs)
+{
+ return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
+}
+
+// This calculates the specular geometric attenuation (aka G()),
+// where rougher material will reflect less light back to the viewer.
+// This implementation is based on [1] Equation 4, and we adopt their modifications to
+// alphaRoughness as input as originally proposed in [2].
+float geometricOcclusion(PBRInfo pbrInputs)
+{
+ float NdotL = pbrInputs.NdotL;
+ float NdotV = pbrInputs.NdotV;
+ float r = pbrInputs.alphaRoughness;
+
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ return attenuationL * attenuationV;
+}
+
+// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
+// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
+// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
+float microfacetDistribution(PBRInfo pbrInputs)
+{
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
+ return roughnessSq / (M_PI * f * f);
+}
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l) //surface point to light
+{
+ // make sure specular highlights from punctual lights don't fall off of polished surfaces
+ perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
+
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
+
+ // Compute reflectance.
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+
+ // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
+ // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
+ vec3 specularEnvironmentR0 = specularColor.rgb;
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
+
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
+
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
+
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
+
+ const vec3 u_LightColor = vec3(1.0);
+
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
+
+ return color;
+}
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor)
+{
+ vec3 f0 = vec3(0.04);
+ diffuseColor = baseColor*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+ specularColor = mix(f0, baseColor, metallic);
+}
+
+vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
+{
+ vec3 color = vec3(0);
+
+ float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
+
+ color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
+
+ color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 2.75 * scol;
+ color += colorEmissive*0.5;
+
+ color = atmosFragLightingLinear(color, additive, atten);
+ color = scaleSoftClipFragLinear(color);
+
+ return color;
+}
+
+uniform vec4 waterPlane;
+uniform float waterSign;
+
+// discard if given position in eye space is on the wrong side of the waterPlane according to waterSign
+void waterClip(vec3 pos)
+{
+ // TODO: make this less branchy
+ if (waterSign > 0)
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < -0.1)
+ {
+ discard;
+ }
+ }
+ else
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > -0.1)
+ {
+ discard;
+ }
+ }
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index b328ee9483..3bf148502c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -53,6 +53,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index fc5c86b4d6..e15239b59d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -52,5 +52,5 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 1bb8eb8bd0..b0ff233414 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -52,6 +52,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 8319e61242..b2d2e2fa71 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -46,6 +46,6 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index ccd1df84f9..b4bc114dd5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -48,5 +48,5 @@ void main()
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 57420158ca..33b97aefcb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -82,7 +82,7 @@ void main()
color.a = final_alpha;
#endif
- frag_color.rgb = color.rgb;
+ frag_color.rgb = srgb_to_linear(color.rgb);
frag_color.a = color.a;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index 9fcee04c32..f693323d45 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -38,7 +38,7 @@ uniform sampler2D diffuseMap;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
+VARYING vec3 vary_position;
uniform samplerCube environmentMap;
@@ -74,7 +74,7 @@ void main()
vec3 amblit;
vec3 additive;
vec3 atten;
- vec3 pos = vary_position.xyz/vary_position.w;
+ vec3 pos = vary_position.xyz;
calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 3bd6b693fa..0e461b4004 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -45,7 +45,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
+VARYING vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
@@ -62,17 +62,18 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vert;
- vary_position = gl_Position = projection_matrix * pos;
+ gl_Position = projection_matrix * pos;
vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#else
vec4 pos = (modelview_matrix * vert);
- vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
#endif
- vec3 ref = reflect(pos.xyz, -norm);
+ vary_position = pos.xyz;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz;
+
+ vary_texcoord1 = norm;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
new file mode 100644
index 0000000000..9e6c853015
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
@@ -0,0 +1,141 @@
+/**
+ * @file class1/deferred/genbrdflut.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/* Taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+VARYING vec2 vary_uv;
+
+out vec4 outColor;
+
+#define NUM_SAMPLES 1024u
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Geometric Shadowing function
+float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
+{
+ float k = (roughness * roughness) / 2.0;
+ float GL = dotNL / (dotNL * (1.0 - k) + k);
+ float GV = dotNV / (dotNV * (1.0 - k) + k);
+ return GL * GV;
+}
+
+vec2 BRDF(float NoV, float roughness)
+{
+ // Normal always points along z-axis for the 2D lookup
+ const vec3 N = vec3(0.0, 0.0, 1.0);
+ vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
+
+ vec2 LUT = vec2(0.0);
+ for(uint i = 0u; i < NUM_SAMPLES; i++) {
+ vec2 Xi = hammersley2d(i, NUM_SAMPLES);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+
+ float dotNL = max(dot(N, L), 0.0);
+ float dotNV = max(dot(N, V), 0.0);
+ float dotVH = max(dot(V, H), 0.0);
+ float dotNH = max(dot(H, N), 0.0);
+
+ if (dotNL > 0.0) {
+ float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
+ float G_Vis = (G * dotVH) / (dotNH * dotNV);
+ float Fc = pow(1.0 - dotVH, 5.0);
+ LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
+ }
+ }
+ return LUT / float(NUM_SAMPLES);
+}
+
+void main()
+{
+ outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
index bc5eb5181d..682244478b 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
@@ -1,9 +1,9 @@
/**
- * @file sunLightV.glsl
+ * @file class3\deferred\genbrdflutV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,15 +27,13 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-VARYING vec2 vary_fragcoord;
-
-uniform vec2 screen_res;
+VARYING vec2 vary_uv;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
-
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
+ vary_uv = position.xy*0.5+0.5;
+
+ gl_Position = vec4(position.xyz, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
index 90566393d2..75f914cb02 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
@@ -38,5 +38,5 @@ void main()
{
frag_data[0] = color*texture2D(diffuseMap, vary_texcoord0.xy);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index a58cc3d12d..51afda2791 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -41,6 +41,7 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
vec3 linear_to_srgb(vec3 c);
+vec2 encode_normal (vec3 n);
void main()
{
@@ -56,5 +57,5 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
- frag_data[2] = norm;
+ frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 02d83925ea..51a36935f2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -23,431 +23,30 @@
* $/LicenseInfo$
*/
+
/*[EXTRA_CODE_HERE]*/
//class1/deferred/materialF.glsl
-// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+// Debug stub for non-pbr material
-#define DIFFUSE_ALPHA_MODE_NONE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
-#define DIFFUSE_ALPHA_MODE_MASK 2
-#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-
-uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
-uniform int sun_up_factor;
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-vec3 srgb_to_linear(vec3 cs);
-vec3 linear_to_srgb(vec3 cs);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
-#define frag_color gl_FragColor
-#endif
-
-#ifdef HAS_SUN_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+out vec4 frag_data[4];
#endif
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-VARYING vec2 vary_fragcoord;
-
-VARYING vec3 vary_position;
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
-{
- // SL-14895 inverted attenuation work-around
- // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
- // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
- // to recover the `adjusted_radius` value previously being sent as la.
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
- // Yes, it makes me want to cry as well. DJH
-
- vec3 col = vec3(0);
-
- //get light vector
- vec3 lv = lp.xyz - v;
-
- //get distance
- float dist = length(lv);
- float da = 1.0;
-
- dist /= inverted_la;
-
- if (dist > 0.0 && inverted_la > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0f;
-
- if (dist_atten <= 0.0)
- {
- return col;
- }
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= dot(n, lv);
-
- float lit = 0.0f;
-
- float amb_da = ambiance;
- if (da >= 0)
- {
- lit = max(da * dist_atten, 0.0);
- col = lit * light_col * diffuse;
- amb_da += (da*0.5 + 0.5) * ambiance;
- }
- amb_da += (da*da*0.5 + 0.5) * ambiance;
- amb_da *= dist_atten;
- amb_da = min(amb_da, 1.0f - lit);
-
- // SL-10969 need to see why these are blown out
- //col.rgb += amb_da * light_col * diffuse;
-
- if (spec.a > 0.0)
- {
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv + npos);
- float nh = dot(n, h);
- float nv = dot(n, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
- vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
- speccol = clamp(speccol, vec3(0), vec3(1));
- col += speccol;
-
- float cur_glare = max(speccol.r, speccol.g);
- cur_glare = max(cur_glare, speccol.b);
- glare = max(glare, speccol.r);
- glare += max(cur_glare, 0.0);
- }
- }
- }
-
- return max(col, vec3(0.0, 0.0, 0.0));
-}
-
-#else
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-#endif
-
-uniform sampler2D diffuseMap; //always in sRGB space
-
-#ifdef HAS_NORMAL_MAP
-uniform sampler2D bumpMap;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-uniform sampler2D specularMap;
-
-VARYING vec2 vary_texcoord2;
-#endif
-
-uniform float env_intensity;
-uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-uniform float minimum_alpha;
-#endif
-
-#ifdef HAS_NORMAL_MAP
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec2 vary_texcoord1;
-#else
-VARYING vec3 vary_normal;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec2 encode_normal(vec3 n);
-
void main()
{
- vec2 pos_screen = vary_texcoord0.xy;
-
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
- // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
- float bias = 0.001953125; // 1/512, or half an 8-bit quantization
- if (diffcol.a < minimum_alpha-bias)
- {
- discard;
- }
-#endif
-
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vec3 gamma_diff = diffcol.rgb;
- diffcol.rgb = srgb_to_linear(diffcol.rgb);
-#endif
-
-#ifdef HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
+ frag_color = vec4(1, 0, 0, 0.5);
#else
- vec4 spec = vec4(specular_color.rgb, 1.0);
-#endif
-
-#ifdef HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
- norm.xyz = norm.xyz * 2 - 1;
-
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
-#else
- vec4 norm = vec4(0,0,0,1.0);
- vec3 tnorm = vary_normal;
-#endif
-
- norm.xyz = normalize(tnorm.xyz);
-
- vec2 abnormal = encode_normal(norm.xyz);
-
- vec4 final_color = diffcol;
-
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- final_color.a = emissive_brightness;
-#else
- final_color.a = max(final_color.a, emissive_brightness);
-#endif
-
- vec4 final_specular = spec;
-
-#ifdef HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
- final_specular.a = specular_color.a * norm.a;
-#else
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
- final_specular.a = specular_color.a;
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
- //forward rendering, output just lit sRGBA
- vec3 pos = vary_position;
-
- float shadow = 1.0f;
-
-#ifdef HAS_SUN_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
-
- spec = final_specular;
- vec4 diffuse = final_color;
- float envIntensity = final_normal.z;
-
- vec3 color = vec3(0,0,0);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
-
- float bloom = 0.0;
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-
- // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
- // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
- // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
- //color = fullbrightScaleSoftClip(color);
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- //we're in sRGB space, so gamma correct this dot product so
- // lighting from the sun stays sharp
- float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
- da = pow(da, 1.0 / 1.3);
-
- color = amblit;
-
- //darken ambient for normals perpendicular to light vector so surfaces in shadow
- // and facing away from light still have some definition to them.
- // do NOT gamma correct this dot product so ambient lighting stays soft
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(da, shadow) * sunlit;
-
- color *= ambient;
-
- color += sun_contrib;
-
- color *= gamma_diff.rgb;
-
- float glare = 0.0;
-
- if (spec.a > 0.0) // specular reflection
- {
- /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020
- // Preserving the refactored version as a comment for potential reconsideration,
- // overriding the general rule to avoid pollutiong the source with commented code.
- //
- // If you're reading this in 2021+, feel free to obliterate.
-
- vec3 npos = -normalize(pos.xyz);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(light_dir.xyz + npos);
- float nh = dot(norm.xyz, h);
- float nv = dot(norm.xyz, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
- vec3 sp = sun_contrib*scol / 6.0f;
- sp = clamp(sp, vec3(0), vec3(1));
- bloom = dot(sp, sp) / 4.0;
- color += sp * spec.rgb;
- }
- */
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
-
- glare = max(spec_contrib.r, spec_contrib.g);
- glare = max(glare, spec_contrib.b);
-
- color += spec_contrib;
- }
-
- color = mix(color.rgb, diffcol.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- {
- //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
-
- color = mix(color, reflected_color, envIntensity);
-
- float cur_glare = max(reflected_color.r, reflected_color.g);
- cur_glare = max(cur_glare, reflected_color.b);
- cur_glare *= envIntensity*4.0;
- glare += cur_glare;
- }
-
- color = atmosFragLighting(color, additive, atten);
- color = scaleSoftClipFrag(color);
-
- //convert to linear before adding local lights
- color = srgb_to_linear(color);
-
- vec3 npos = normalize(-pos.xyz);
-
- vec3 light = vec3(0, 0, 0);
-
- final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035
-
-#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- color += light;
-
- glare = min(glare, 1.0);
- float al = max(diffcol.a, glare)*vertex_color.a;
-
- //convert to srgb as this color is being written post gamma correction
- color = linear_to_srgb(color);
-
-#ifdef WATER_FOG
- vec4 temp = applyWaterFogView(pos, vec4(color, al));
- color = temp.rgb;
- al = temp.a;
-#endif
-
- frag_color = vec4(color, al);
-
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
-
- // deferred path
- frag_data[0] = final_color; //gbuffer is sRGB
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+ // emissive red PBR material
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(1, 0, 0, 0);
#endif
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 7e29ada205..a1cab87092 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -1,5 +1,5 @@
/**
- * @file bumpV.glsl
+ * @file materialV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 35068899ee..b4044353b4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -34,8 +34,7 @@ out vec4 frag_data[3];
#endif
uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 moonlight_color;
uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
@@ -66,7 +65,7 @@ void main()
frag_data[0] = vec4(c.rgb, c.a);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
gl_FragDepth = 0.999985f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 09c47165dd..0ae4bbfc5d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -36,7 +36,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index ec3fb9c543..8dcc18080d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -42,7 +42,6 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
index 8f32dfde79..fc1024f4f1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shVisV.glsl
+ * @file class1\deferred\pbralphaF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,13 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-VARYING vec4 vary_pos;
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
void main()
{
- // Output
- vary_pos = vec4(position, 1);
- gl_Position = vary_pos;
+ frag_color = vec4(0,1,0,0.5);
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
new file mode 100644
index 0000000000..d0d76fd0cb
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -0,0 +1,115 @@
+/**
+ * @file class1\deferred\pbralphaV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ uniform mat4 modelview_matrix;
+ #endif
+ VARYING vec3 vary_position;
+#endif
+
+uniform mat4 texture_matrix0;
+
+#ifdef HAS_SUN_SHADOW
+VARYING vec3 vary_fragcoord;
+uniform float near_clip;
+#endif
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat out float vary_sign;
+
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vary_position = pos;
+#endif
+ vec4 vert = projection_matrix * vec4(pos,1.0);
+#else
+ //transform vertex
+ vec4 vert = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+ gl_Position = vert;
+
+#ifdef HAS_SUN_SHADOW
+ vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif //HAS_SKIN
+
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ vertex_color = diffuse_color;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+ #endif
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
new file mode 100644
index 0000000000..7376e9eb47
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -0,0 +1,105 @@
+/**
+ * @file pbropaqueF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
+
+out vec4 frag_data[4];
+
+VARYING vec3 vary_position;
+VARYING vec4 vertex_color;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform mat3 normal_matrix;
+
+void main()
+{
+// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+// else
+ vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba;
+ if (albedo.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb);
+
+ // from mikktspace.com
+ vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerTexture::sDefaultPBRORMImagep
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+ vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb;
+
+ spec.g *= roughnessFactor;
+ spec.b *= metallicFactor;
+
+ vec3 emissive = emissiveColor;
+ emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
+
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ //spec.rgb = vec3(1,1,0);
+ //col = vec3(0,0,0);
+ //emissive = vary_tangent.xyz*0.5+0.5;
+ //emissive = vec3(sign*0.5+0.5);
+ //emissive = vNt * 0.5 + 0.5;
+ //emissive = tnorm*0.5+0.5;
+ // See: C++: addDeferredAttachments(), GLSL: softenLightF
+ frag_data[0] = vec4(col, 0.0); // Diffuse
+ frag_data[1] = vec4(spec.rgb,vertex_color.a); // PBR linear packed Occlusion, Roughness, Metal.
+ frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
+ frag_data[3] = vec4(emissive,0); // PBR sRGB Emissive
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
new file mode 100644
index 0000000000..5573c02a60
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -0,0 +1,92 @@
+/**
+ * @file pbropaqueV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+
+VARYING vec4 vertex_color;
+
+VARYING vec3 vary_tangent;
+flat out float vary_sign;
+VARYING vec3 vary_normal;
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+
+ mat = modelview_matrix * mat;
+
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+ gl_Position = projection_matrix*vec4(pos,1.0);
+
+#else
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif
+
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 18616a9bb3..5bb034d5c1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file pointLightF.glsl
+ * @file class1\deferred\pointLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,7 +36,6 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
uniform sampler2DRect depthMap;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index cd37a34e0d..b61f37fe47 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -41,12 +41,53 @@ uniform float display_gamma;
vec3 linear_to_srgb(vec3 cl);
+//=================================
+// borrowed noise from:
+// <https://www.shadertoy.com/view/4dS3Wd>
+// By Morgan McGuire @morgan3d, http://graphicscodex.com
+//
+float hash(float n) { return fract(sin(n) * 1e4); }
+float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }
+
+float noise(float x) {
+ float i = floor(x);
+ float f = fract(x);
+ float u = f * f * (3.0 - 2.0 * f);
+ return mix(hash(i), hash(i + 1.0), u);
+}
+
+float noise(vec2 x) {
+ vec2 i = floor(x);
+ vec2 f = fract(x);
+
+ // Four corners in 2D of a tile
+ float a = hash(i);
+ float b = hash(i + vec2(1.0, 0.0));
+ float c = hash(i + vec2(0.0, 1.0));
+ float d = hash(i + vec2(1.0, 1.0));
+
+ // Simple 2D lerp using smoothstep envelope between the values.
+ // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
+ // mix(c, d, smoothstep(0.0, 1.0, f.x)),
+ // smoothstep(0.0, 1.0, f.y)));
+
+ // Same code, with the clamps in smoothstep and common subexpressions
+ // optimized away.
+ vec2 u = f * f * (3.0 - 2.0 * f);
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
+}
+
+//=============================
+
void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- //diff.rgb = pow(diff.rgb, vec3(display_gamma));
diff.rgb = linear_to_srgb(diff.rgb);
+ vec3 seed = (diff.rgb+vec3(1.0))*vec3(vary_fragcoord.xy, vary_fragcoord.x+vary_fragcoord.y);
+ vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
+ diff.rgb += nz*0.008;
+ //diff.rgb = nz;
frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..dd850ff97c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @file class1/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// fallback stub -- will be used if actual reflection probe shader failed to load (output pink so it's obvious)
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ ambenv = vec3(1,0,1);
+ glossenv = vec3(1,0,1);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ ambenv = vec3(1,0,1);
+ glossenv = vec3(1,0,1);
+ legacyenv = vec3(1,0,1);
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+
+}
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+{
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 331249dc33..adc2db60b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -35,7 +35,7 @@ out vec4 frag_data[3];
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
@@ -48,7 +48,7 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec4 color;
+ vec3 color;
color = vary_HazeColor;
color.rgb *= 2.;
@@ -57,7 +57,7 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 0.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
+ frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
gl_FragDepth = 0.99999f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 28a1faf24f..ff53646fd4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -32,18 +32,18 @@ ATTRIBUTE vec3 position;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -52,11 +52,9 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
-
// NOTE: Keep these in sync!
// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
@@ -87,17 +85,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec4 light_atten;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -125,21 +123,21 @@ void main()
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
- vec4 color =
+ vec3 color =
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 7f2c603f87..4b34e55efd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -142,7 +142,7 @@ void main()
color = mix(color.rgb, reflected_color, envIntensity);
}
- if (norm.w < 0.5)
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
@@ -156,12 +156,6 @@ void main()
}
-// linear debuggables
-//color.rgb = vec3(final_da);
-//color.rgb = vec3(ambient);
-//color.rgb = vec3(scol);
-//color.rgb = diffuse_srgb.rgb;
-
// convert to linear as fullscreen lights need to sum in linear colorspace
// and will be gamma (re)corrected downstream...
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index bac79a9fdc..ef9cee3fa0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -60,7 +60,7 @@ void main()
frag_data[0] = col;
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.99995f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index b2fa5d8a25..4ab8747629 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -57,7 +57,7 @@ void main()
frag_data[0] = c;
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
gl_FragDepth = 0.999988f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 6b6eed9db8..d6c14c48c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -63,6 +63,6 @@ void main()
frag_data[0] = outColor;
frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 89e354558a..dc0e5b0ce3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -52,5 +52,5 @@ void main()
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
index 9a5debb3c1..14c337e608 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -78,5 +78,5 @@ void main()
frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, env intens, atmo kill
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, GBUFFER_FLAG_HAS_ATMOS); // normalxyz, env intens, flags (atmo kill)
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index a157e9c017..876422f86b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -22,163 +22,15 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
+// debug stub
+out vec4 frag_data[4];
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
-uniform int water_edge;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec2 encode_normal(vec3 n);
-vec3 scaleSoftClip(vec3 l);
-vec3 srgb_to_linear(vec3 c);
-vec3 linear_to_srgb(vec3 c);
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
+void main()
{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
-}
-
-void main()
-{
- vec4 color;
- float dist = length(view.xyz);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
-
- refcol = mix(baseCol*df2, refcol, dweight);
-
- //get specular component
- float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999f);
-
- vec4 pos = vary_position;
-
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
-
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
-
- //frag_data[0] = color;
-
- // TODO: The non-obvious assignment below is copied from the pre-EEP WL shader code
- // Unfortunately, fixing it causes a mismatch for EEP, and so it remains... for now
- // SL-12975 (unfix pre-EEP broken alpha)
- frag_data[0] = vec4(color.rgb, color); // Effectively, color.rgbr
-
-
- frag_data[1] = vec4(0); // speccolor, spec
- frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
+ // emissive blue PBR material
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(0, 0, 1, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 8c8bd6d0d5..ad105c616c 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -23,55 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform sampler2D screenDepth;
-
-uniform vec4 fogCol;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform vec2 fbScale;
-uniform float refScale;
-uniform float znear;
-uniform float zfar;
-uniform float kd;
-uniform vec4 waterPlane;
-uniform vec3 eyeVec;
-uniform vec4 waterFogColor;
-uniform float waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+// debug stub
void main()
{
- vec4 color;
-
- //get detail normals
- vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wavef = normalize(wave1+wave2+wave3);
-
- //figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
-
- vec4 fb = texture2D(screenTex, distort);
-
- frag_color = applyWaterFogView(view.xyz, fb);
+ frag_color = vec4(0, 1, 1, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index d370997123..46a6c2021d 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -23,146 +23,9 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
+void main()
{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
+ frag_color = vec4(0, 0, 1, 0);
}
-
-
-void main()
-{
- vec4 color;
-
- float dist = length(view.xy);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec2 bigwave = vec2(refCoord.w, view.w);
- vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
-
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
- refcol = mix(baseCol*df2, refcol, dweight);
-
- //get specular component
- float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
- color.a = spec * sunAngle2;
-
- frag_color = color;
-
-#if defined(WATER_EDGE)
- gl_FragDepth = 0.9999847f;
-#endif
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index df640cba05..011b3c8643 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -32,6 +32,8 @@ uniform float waterFogKS;
vec3 getPositionEye();
+vec3 srgb_to_linear(vec3 col);
+
vec4 applyWaterFogView(vec3 pos, vec4 color)
{
vec3 view = normalize(pos);
@@ -71,6 +73,52 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
return color;
}
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
+{
+ if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+ {
+ return color;
+ }
+
+ vec3 view = normalize(pos);
+ //normalize view vector
+ float es = -(dot(view, waterPlane.xyz));
+
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w / es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+ kc.rgb = srgb_to_linear(kc.rgb); // TODO -- pass in waterFogColor linear
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2 * l) - 1.0;
+
+ float L = min(t1 / t2 * t3, 1.0);
+
+ float D = pow(0.98, l * kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+
vec4 applyWaterFog(vec4 color)
{
//normalize view vector
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index cc41e3f740..a0a0e7dfca 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -24,6 +24,7 @@
*/
uniform mat4 modelview_matrix;
+uniform mat3 normal_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
@@ -36,10 +37,16 @@ uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
+uniform vec3 lightDir;
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+out vec3 vary_position;
+out vec3 vary_light_dir;
+out vec3 vary_tangent;
+out vec3 vary_normal;
+out vec2 vary_fragcoord;
float wave(vec2 v, float t, float f, vec2 d, float s)
{
@@ -52,6 +59,11 @@ void main()
vec4 pos = vec4(position.xyz, 1.0);
mat4 modelViewProj = modelview_projection_matrix;
+ vary_position = (modelview_matrix * pos).xyz;
+ vary_light_dir = normal_matrix * lightDir;
+ vary_normal = normal_matrix * vec3(0, 0, 1);
+ vary_tangent = normal_matrix * vec3(1, 0, 0);
+
vec4 oPosition;
//get view vector
@@ -63,12 +75,13 @@ void main()
pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
view.xyz = oEyeVec;
-
+
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
d *= d;
oPosition = vec4(position, 1.0);
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+
oPosition = modelViewProj * oPosition;
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
@@ -83,8 +96,7 @@ void main()
pos = modelview_matrix*pos;
calcAtmospherics(pos.xyz);
-
-
+
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
//get two normal map (detail map) texture coordinates
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
new file mode 100644
index 0000000000..feaf562686
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -0,0 +1,227 @@
+/**
+ * @file irradianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+VARYING vec3 vary_dir;
+
+
+// Code below is derived from the Khronos GLTF Sample viewer:
+// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag
+
+
+#define MATH_PI 3.1415926535897932384626433832795
+
+float u_roughness = 1.0;
+int u_sampleCount = 16;
+float u_lodBias = 2.0;
+int u_width = 64;
+
+// Hammersley Points on the Hemisphere
+// CC BY 3.0 (Holger Dammertz)
+// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+// with adapted interface
+float radicalInverse_VdC(uint bits)
+{
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
+// that can be used for quasi Monte Carlo integration
+vec2 hammersley2d(int i, int N) {
+ return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
+}
+
+// Hemisphere Sample
+
+// TBN generates a tangent bitangent normal coordinate frame from the normal
+// (the normal must be normalized)
+mat3 generateTBN(vec3 normal)
+{
+ vec3 bitangent = vec3(0.0, 1.0, 0.0);
+
+ float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0));
+ float epsilon = 0.0000001;
+ /*if (1.0 - abs(NdotUp) <= epsilon)
+ {
+ // Sampling +Y or -Y, so we need a more robust bitangent.
+ if (NdotUp > 0.0)
+ {
+ bitangent = vec3(0.0, 0.0, 1.0);
+ }
+ else
+ {
+ bitangent = vec3(0.0, 0.0, -1.0);
+ }
+ }*/
+
+ vec3 tangent = normalize(cross(bitangent, normal));
+ bitangent = cross(normal, tangent);
+
+ return mat3(tangent, bitangent, normal);
+}
+
+struct MicrofacetDistributionSample
+{
+ float pdf;
+ float cosTheta;
+ float sinTheta;
+ float phi;
+};
+
+MicrofacetDistributionSample Lambertian(vec2 xi, float roughness)
+{
+ MicrofacetDistributionSample lambertian;
+
+ // Cosine weighted hemisphere sampling
+ // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling
+ lambertian.cosTheta = sqrt(1.0 - xi.y);
+ lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`;
+ lambertian.phi = 2.0 * MATH_PI * xi.x;
+
+ lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta
+
+ return lambertian;
+}
+
+
+// getImportanceSample returns an importance sample direction with pdf in the .w component
+vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness)
+{
+ // generate a quasi monte carlo point in the unit square [0.1)^2
+ vec2 xi = hammersley2d(sampleIndex, u_sampleCount);
+
+ MicrofacetDistributionSample importanceSample;
+
+ // generate the points on the hemisphere with a fitting mapping for
+ // the distribution (e.g. lambertian uses a cosine importance)
+ importanceSample = Lambertian(xi, roughness);
+
+ // transform the hemisphere sample to the normal coordinate frame
+ // i.e. rotate the hemisphere to the normal direction
+ vec3 localSpaceDirection = normalize(vec3(
+ importanceSample.sinTheta * cos(importanceSample.phi),
+ importanceSample.sinTheta * sin(importanceSample.phi),
+ importanceSample.cosTheta
+ ));
+ mat3 TBN = generateTBN(N);
+ vec3 direction = TBN * localSpaceDirection;
+
+ return vec4(direction, importanceSample.pdf);
+}
+
+// Mipmap Filtered Samples (GPU Gems 3, 20.4)
+// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
+// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+float computeLod(float pdf)
+{
+ // // Solid angle of current sample -- bigger for less likely samples
+ // float omegaS = 1.0 / (float(u_sampleCount) * pdf);
+ // // Solid angle of texel
+ // // note: the factor of 4.0 * MATH_PI
+ // float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width));
+ // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
+ // // note that 0.5 * log2 is equivalent to log4
+ // float lod = 0.5 * log2(omegaS / omegaP);
+
+ // babylon introduces a factor of K (=4) to the solid angle ratio
+ // this helps to avoid undersampling the environment map
+ // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert
+ // log4(4) == 1
+ // lod += 1.0;
+
+ // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps
+
+ // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+ float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf));
+
+
+ return lod;
+}
+
+vec4 filterColor(vec3 N)
+{
+ //return textureLod(uCubeMap, N, 3.0).rgb;
+ vec4 color = vec4(0.f);
+ float weight = 0.0f;
+
+ for(int i = 0; i < u_sampleCount; ++i)
+ {
+ vec4 importanceSample = getImportanceSample(i, N, 1.0);
+
+ vec3 H = vec3(importanceSample.xyz);
+ float pdf = importanceSample.w;
+
+ // mipmap filtered samples (GPU Gems 3, 20.4)
+ float lod = computeLod(pdf);
+
+ // apply the bias to the lod
+ lod += u_lodBias;
+
+ lod = clamp(lod, 0, 6);
+ // sample lambertian at a lower resolution to avoid fireflies
+ vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);
+
+ color += lambertian;
+ }
+
+ if(weight != 0.0f)
+ {
+ color /= weight;
+ }
+ else
+ {
+ color /= float(u_sampleCount);
+ }
+
+ return color;
+}
+
+// entry point
+void main()
+{
+ vec4 color = vec4(0);
+
+ color = filterColor(vary_dir);
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
index b466883dc7..5190abf17c 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
@@ -1,9 +1,9 @@
/**
- * @file genSkyShV.glsl
+ * @file irradianceGenV.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * 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
@@ -22,16 +22,17 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+uniform mat4 modelview_matrix;
+
ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-VARYING vec2 vary_frag;
+VARYING vec3 vary_dir;
void main()
{
- // pass through untransformed fullscreen pos
- gl_Position = vec4(position.xyz, 1.0);
- vary_frag = texcoord0;
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456c..f5d2804c7f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,13 +23,13 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+out vec4 frag_data[4];
void main()
{
- frag_color = vec4(1,1,1,1);
+ // emissive red PBR material for debugging
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(1, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
new file mode 100644
index 0000000000..32f157e9d2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -0,0 +1,169 @@
+/**
+ * @file radianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+VARYING vec3 vary_dir;
+
+//uniform float roughness;
+
+uniform float mipLevel;
+
+// =============================================================================================================
+// Parts of this file are (c) 2018 Sascha Willems
+// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/prefilterenvmap.frag
+/*
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+*/
+// =============================================================================================================
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Normal Distribution function
+float D_GGX(float dotNH, float roughness)
+{
+ float alpha = roughness * roughness;
+ float alpha2 = alpha * alpha;
+ float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
+ return (alpha2)/(PI * denom*denom);
+}
+
+vec4 prefilterEnvMap(vec3 R)
+{
+ vec3 N = R;
+ vec3 V = R;
+ vec4 color = vec4(0.0);
+ float totalWeight = 0.0;
+ float envMapDim = 256.0;
+ int numSamples = 4;
+
+ float numMips = 6.0;
+
+ float roughness = mipLevel/numMips;
+
+ numSamples = max(int(numSamples*roughness), 1);
+
+ for(uint i = 0u; i < numSamples; i++) {
+ vec2 Xi = hammersley2d(i, numSamples);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+ float dotNL = clamp(dot(N, L), 0.0, 1.0);
+ if(dotNL > 0.0) {
+ // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
+
+ float dotNH = clamp(dot(N, H), 0.0, 1.0);
+ float dotVH = clamp(dot(V, H), 0.0, 1.0);
+
+ // Probability Distribution Function
+ float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
+ // Slid angle of current smple
+ float omegaS = 1.0 / (float(numSamples) * pdf);
+ // Solid angle of 1 pixel across all cube faces
+ float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
+ // Biased (+1.0) mip level for better result
+ float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, numMips);
+ //float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
+ color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL;
+ totalWeight += dotNL;
+
+ }
+ }
+ return (color / totalWeight);
+}
+
+void main()
+{
+ vec3 N = normalize(vary_dir);
+ frag_color = prefilterEnvMap(N);
+}
+// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
index 2eb222ada4..5f5d9396ff 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/skyV.glsl
+ * @file radianceGenV.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * 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
@@ -22,16 +22,17 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+uniform mat4 modelview_matrix;
+
ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-VARYING vec2 vary_frag;
+VARYING vec3 vary_dir;
void main()
{
- // pass through untransformed fullscreen pos at back of frustum for proper sky depth testing
- gl_Position = vec4(position.xy, 1.0f, 1.0);
- vary_frag = texcoord0;
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
new file mode 100644
index 0000000000..9dd97a80b2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -0,0 +1,101 @@
+/**
+ * @file reflectionmipF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+// NOTE screenMap should always be texture channel 0 and
+// depthmap should always be channel 1
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect depthMap;
+
+uniform float resScale;
+uniform float znear;
+uniform float zfar;
+
+VARYING vec2 vary_texcoord0;
+
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar);
+
+void main()
+{
+#if 0
+ float w[9];
+
+ float c = 1.0/16.0; //corner weight
+ float e = 1.0/8.0; //edge weight
+ float m = 1.0/4.0; //middle weight
+
+ //float wsum = c*4+e*4+m;
+
+ w[0] = c; w[1] = e; w[2] = c;
+ w[3] = e; w[4] = m; w[5] = e;
+ w[6] = c; w[7] = e; w[8] = c;
+
+ vec2 tc[9];
+
+ float ed = 1;
+ float cd = 1;
+
+
+ tc[0] = vec2(-cd, cd); tc[1] = vec2(0, ed); tc[2] = vec2(cd, cd);
+ tc[3] = vec2(-ed, 0); tc[4] = vec2(0, 0); tc[5] = vec2(ed, 0);
+ tc[6] = vec2(-cd, -cd); tc[7] = vec2(0, -ed); tc[8] = vec2(cd, -1);
+
+ vec3 color = vec3(0,0,0);
+
+ for (int i = 0; i < 9; ++i)
+ {
+ color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i];
+ //color += texture2DRect(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5;
+ }
+
+ //color /= wsum;
+
+ frag_color = vec4(color, 1.0);
+#else
+ vec2 depth_tc = vary_texcoord0.xy * resScale;
+ float depth = texture(depthMap, depth_tc).r;
+ float dist = linearDepth(depth, znear, zfar);
+
+ // convert linear depth to distance
+ vec3 v;
+ v.xy = depth_tc / 512.0 * 2.0 - 1.0;
+ v.z = 1.0;
+ v = normalize(v);
+ dist /= v.z;
+
+ vec3 col = texture2DRect(diffuseRect, vary_texcoord0.xy).rgb;
+ frag_color = vec4(col, dist/256.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index ea2690ba09..12f500e224 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -22,113 +22,26 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-uniform vec4 glow;
-uniform float scene_light_strength;
-uniform mat3 ssao_effect_mat;
-uniform int no_atmo;
-uniform float sun_moon_glow_factor;
+
+// debug stub
float getAmbientClamp() { return 1.0f; }
+// Returns colors in sRGB
void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
out vec3 atten, bool use_ao)
{
- vec3 rel_pos = inPositionEye;
-
- //(TERRAIN) limit altitude
- if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
-
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-
- // sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
- // I had thought blue_density and haze_density should have equal weighting,
- // but attenuation due to haze_density tends to seem too strong
-
- vec4 combined_haze = blue_density + vec4(haze_density);
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = vec4(haze_density) / combined_haze;
-
- //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
- float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
- sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
-
- // main atmospheric scattering line integral
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
-
- // final atmosphere attenuation factor
- atten = combined_haze.rgb;
-
- // compute haze glow
- float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
-
- // dampen sun additive contrib when not facing it...
- // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
- // if (length(light_dir) > 0.01)
- haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
-
- haze_glow = 1. - haze_glow;
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // add "minimum anti-solar illumination"
- haze_glow += .25;
-
- haze_glow *= sun_moon_glow_factor;
-
- vec4 amb_color = ambient_color;
-
- // increase ambient when there are more clouds
- vec4 tmpAmbient = amb_color + (vec4(1.) - amb_color) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat,
- * ambAlpha);
- */
- if (use_ao)
- {
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
- }
-
- // Similar/Shared Algorithms:
- // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
- // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
- // haze color
- vec3 cs = sunlight.rgb * (1. - cloud_shadow);
- additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+ amblit = vec3(0.2, 0, 0.2);
+ sunlit = vec3(1,0,1);
+ additive = vec3(0.5,0.5,0.5);
+ atten = vec3(1,0,1);
+}
- // brightness of surface both sunlight and ambient
- sunlit = sunlight.rgb * 0.5;
- amblit = tmpAmbient.rgb * .25;
- additive *= vec3(1.0 - combined_haze);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten)
+{
+ amblit = vec3(0.2, 0, 0.2);
+ sunlit = vec3(1,0,1);
+ additive = vec3(0.5,0.5,0.5);
+ atten = vec3(1,0,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
deleted file mode 100644
index 82fad4db5a..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class1/windlight/cloudShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- if (cloud_scale >= 0.0001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
deleted file mode 100644
index 09b6004481..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class1\windlight\cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
index 2425a2ad04..f03003f5e1 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -34,8 +34,7 @@ out vec4 frag_color;
#endif
uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 moonlight_color;
uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
new file mode 100644
index 0000000000..e255c78b86
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -0,0 +1,306 @@
+/**
+ * @file alphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+//class2/deferred/alphaF.glsl
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#define INDEXED 1
+#define NON_INDEXED 2
+#define NON_INDEXED_NO_COLOR 3
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform mat3 env_mat;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+#ifdef USE_DIFFUSE_TEX
+uniform sampler2D diffuseMap;
+#endif
+
+VARYING vec3 vary_fragcoord;
+VARYING vec3 vary_position;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
+
+#ifdef USE_VERTEX_COLOR
+VARYING vec4 vertex_color; //vertex color should be treated as sRGB
+#endif
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha;
+#endif
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+uniform int sun_up_factor;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+void waterClip(vec3 pos);
+
+#ifdef WATER_FOG
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+#endif
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+vec2 encode_normal (vec3 n);
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+float getAmbientClamp();
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ /*if (dist > inverted_la)
+ {
+ return col;
+ }
+
+ clip to projector bounds
+ vec4 proj_tc = proj_mat * lp;
+
+ if (proj_tc.z < 0
+ || proj_tc.z > 1
+ || proj_tc.x < 0
+ || proj_tc.x > 1
+ || proj_tc.y < 0
+ || proj_tc.y > 1)
+ {
+ return col;
+ }*/
+
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
+ dist /= inverted_la;
+
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0f;
+
+ if (dist_atten <= 0.0)
+ {
+ return col;
+ }
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= dot(n, lv);
+ da = max(0.0, da);
+
+ float lit = 0.0f;
+
+ float amb_da = 0.0;//ambiance;
+ if (da > 0)
+ {
+ lit = max(da * dist_atten,0.0);
+ col = lit * light_col * diffuse;
+ amb_da += (da*0.5+0.5) * ambiance;
+ }
+ amb_da += (da*da*0.5 + 0.5) * ambiance;
+ amb_da *= dist_atten;
+ amb_da = min(amb_da, 1.0f - lit);
+
+ // SL-10969 ... need to work out why this blows out in many setups...
+ //col.rgb += amb_da * light_col * diffuse;
+
+ // no spec for alpha shader...
+ }
+ col = max(col, vec3(0));
+ return col;
+}
+
+void main()
+{
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ frag *= screen_res;
+
+ vec4 pos = vec4(vary_position, 1.0);
+#ifndef IS_AVATAR_SKIN
+ // clip against water plane unless this is a legacy avatar skin
+ waterClip(pos.xyz);
+#endif
+ vec3 norm = vary_norm;
+
+ float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
+
+#ifdef USE_DIFFUSE_TEX
+ vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
+#endif
+
+#ifdef USE_INDEXED_TEX
+ vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
+#endif
+
+ vec4 diffuse_srgb = diffuse_tap;
+
+#ifdef FOR_IMPOSTOR
+ vec4 color;
+ color.rgb = diffuse_srgb.rgb;
+ color.a = 1.0;
+
+ float final_alpha = diffuse_srgb.a * vertex_color.a;
+ diffuse_srgb.rgb *= vertex_color.rgb;
+
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < minimum_alpha)
+ {
+ discard;
+ }
+
+ color.rgb = diffuse_srgb.rgb;
+ color.a = final_alpha;
+
+#else // FOR_IMPOSTOR
+
+ vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
+
+ float final_alpha = diffuse_linear.a;
+
+#ifdef USE_VERTEX_COLOR
+ final_alpha *= vertex_color.a;
+
+ if (final_alpha < minimum_alpha)
+ { // TODO: figure out how to get invisible faces out of
+ // render batches without breaking glow
+ discard;
+ }
+
+ diffuse_srgb.rgb *= vertex_color.rgb;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
+#endif // USE_VERTEX_COLOR
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 irradiance;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, 0.0, 0.0);
+
+
+ float da = dot(norm.xyz, light_dir.xyz);
+ da = clamp(da, -1.0, 1.0);
+
+ float final_da = da;
+ final_da = clamp(final_da, 0.0f, 1.0f);
+
+ vec4 color = vec4(0.0);
+
+ color.a = final_alpha;
+
+ vec3 sun_contrib = min(final_da, shadow) * sunlit;
+
+ color.rgb = max(amblit, irradiance);
+
+ color.rgb += sun_contrib;
+
+ color.rgb *= diffuse_linear.rgb;
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+ vec4 light = vec4(0,0,0,0);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ // sum local light contrib in linear colorspace
+#if !defined(LOCAL_LIGHT_KILL)
+ color.rgb += light.rgb;
+#endif // !defined(LOCAL_LIGHT_KILL)
+
+#ifdef WATER_FOG
+ color = applyWaterFogViewLinear(pos.xyz, color);
+#endif // WATER_FOG
+
+#endif // #else // FOR_IMPOSTOR
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
new file mode 100644
index 0000000000..b39f834e41
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -0,0 +1,239 @@
+/**
+ * @file class1\deferred\pbralphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D diffuseMap; //always in sRGB space
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // PBR: Packed: Occlusion, Metal, Roughness
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+uniform sampler2DRect lightMap;
+#endif
+
+uniform int sun_up_factor;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+out vec4 frag_color;
+
+#ifdef HAS_SUN_SHADOW
+ VARYING vec3 vary_fragcoord;
+ uniform vec2 screen_res;
+#endif
+
+VARYING vec3 vary_position;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
+
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+#endif
+
+// Lights
+// See: LLRender::syncLightState()
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8]; // spot direction
+uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState()
+uniform vec3 light_diffuse[8];
+uniform vec2 light_deferred_attenuation[8]; // light size and falloff
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness);
+
+void waterClip(vec3 pos);
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 p, // pixel position
+ vec3 v, // view vector (negative normalized pixel position)
+ vec3 lp, // light position
+ vec3 ld, // light direction (for spotlights)
+ vec3 lightColor,
+ float lightSize, float falloff, float is_pointlight, float ambiance)
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 lv = lp.xyz - p;
+
+ float lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ld, lv), is_pointlight);
+ // spot*spot => GL_SPOT_EXPONENT=2
+ float spot_atten = spot*spot;
+
+ vec3 intensity = spot_atten * dist_atten * lightColor * 3.0;
+
+ color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+
+ return color;
+}
+
+void main()
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ vec3 pos = vary_position;
+
+ waterClip(pos);
+
+// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+// else
+ vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba;
+ albedo.rgb = srgb_to_linear(albedo.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (albedo.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ vec3 baseColor = vertex_color.rgb * albedo.rgb;
+
+ vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ norm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ float scol = 1.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+#ifdef HAS_SUN_SHADOW
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+ frag *= screen_res;
+ scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
+
+ vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+
+ float perceptualRoughness = orm.g * roughnessFactor;
+ float metallic = orm.b * metallicFactor;
+ float ao = orm.r;
+
+ // emissiveColor is the emissive color factor from GLTF and is already in linear space
+ vec3 colorEmissive = emissiveColor;
+ // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
+ colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+ // Take maximium of legacy ambient vs irradiance sample as irradiance
+ // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
+ irradiance = max(amblit,irradiance);
+
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
+
+ vec3 v = -normalize(pos.xyz);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+
+ vec3 light = vec3(0);
+
+ // Punctual lights
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color.rgb += light.rgb;
+
+
+ frag_color = vec4(color.rgb,albedo.a * vertex_color.a);
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..eb26143438
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -0,0 +1,75 @@
+/**
+ * @file class2/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Implementation for when reflection probes are disabled
+
+uniform float reflection_probe_ambiance;
+
+uniform samplerCube environmentMap;
+
+uniform mat3 env_mat;
+
+vec3 srgb_to_linear(vec3 c);
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+ glossenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+
+ legacyenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
+
+ glossenv = legacyenv;
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+
+}
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+{
+ color = mix(color.rgb, legacyenv*1.5, envIntensity);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
index 6841a8194f..668f70c3ab 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -32,13 +32,13 @@ uniform mat4 modelview_projection_matrix;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -47,10 +47,10 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -123,16 +123,16 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
@@ -162,7 +162,7 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
// Haze color above cloud
- vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ vec3 color = blue_horizon * blue_weight * (sunlight + ambient_color)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
// Final atmosphere additive
@@ -170,13 +170,13 @@ void main()
// Increase ambient when there are more clouds
// TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
- vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ vec3 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
// Attenuate cloud color by atmosphere
@@ -195,5 +195,5 @@ void main()
// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
- frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS); // 1.0 in norm.w masks off fog
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 7700d16007..677c9c244c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -88,7 +88,7 @@ void main()
da = pow(da, light_gamma);
vec4 diffuse = texture2DRect(diffuseRect, tc);
- diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
@@ -139,7 +139,7 @@ void main()
color = mix(color.rgb, reflected_color, envIntensity);
}
- if (norm.w < 0.5)
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
{
color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl
new file mode 100644
index 0000000000..96739d91d7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl
@@ -0,0 +1,192 @@
+/**
+ * @file class1/deferred/waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[4];
+#else
+#define frag_data gl_FragData
+#endif
+
+vec3 scaleSoftClip(vec3 inColor);
+vec3 atmosTransport(vec3 inColor);
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec2 screen_res;
+uniform mat4 norm_mat; //region space to screen space
+uniform int water_edge;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+VARYING vec4 vary_position;
+
+vec2 encode_normal(vec3 n);
+vec3 scaleSoftClip(vec3 l);
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+void main()
+{
+ vec4 color;
+ float dist = length(view.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(view.xyz);
+
+ //get wave normals
+ vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+
+ vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+ df *= df;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ //get reflected color
+ vec2 refdistort1 = wave1.xy*normScale.x;
+ vec2 refvec1 = distort+refdistort1/dmod_scale;
+ vec4 refcol1 = texture2D(refTex, refvec1);
+
+ vec2 refdistort2 = wave2.xy*normScale.y;
+ vec2 refvec2 = distort+refdistort2/dmod_scale;
+ vec4 refcol2 = texture2D(refTex, refvec2);
+
+ vec2 refdistort3 = wave3.xy*normScale.z;
+ vec2 refvec3 = distort+refdistort3/dmod_scale;
+ vec4 refcol3 = texture2D(refTex, refvec3);
+
+ vec4 refcol = refcol1 + refcol2 + refcol3;
+ float df1 = df.x + df.y + df.z;
+ refcol *= df1 * 0.333;
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ wavef.z *= max(-viewVec.z, 0.1);
+ wavef = normalize(wavef);
+
+ float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
+
+ vec2 refdistort4 = wavef.xy*0.125;
+ refdistort4.y -= abs(refdistort4.y);
+ vec2 refvec4 = distort+refdistort4/dmod;
+ float dweight = min(dist2*blurMultiplier, 1.0);
+ vec4 baseCol = texture2D(refTex, refvec4);
+
+ refcol = mix(baseCol*df2, refcol, dweight);
+
+ //get specular component
+ float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
+
+ //harden specular
+ spec = pow(spec, 128.0);
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
+
+ vec4 fb = texture2D(screenTex, distort2);
+
+ //mix with reflection
+ // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
+ color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999f);
+
+ vec4 pos = vary_position;
+
+ //color.rgb += spec * specular;
+
+ //color.rgb = atmosTransport(color.rgb);
+ //color.rgb = scaleSoftClip(color.rgb);
+
+ //color.rgb = refcol.rgb;
+ color.rgb = vec3(0.0);
+ color.a = spec * sunAngle2;
+
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+
+ //frag_data[0] = color;
+
+ // TODO: The non-obvious assignment below is copied from the pre-EEP WL shader code
+ // Unfortunately, fixing it causes a mismatch for EEP, and so it remains... for now
+ // SL-12975 (unfix pre-EEP broken alpha)
+ frag_data[0] = vec4(srgb_to_linear(color.rgb), 0.0);
+
+ frag_data[1] = vec4(1.0, 0.1, 0.0, 0.0); // occlusion, roughness, metalness
+ frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.0, GBUFFER_FLAG_HAS_PBR);// normalxy, env intens, flags (atmo kill)
+ //frag_data[3] = vec4(srgb_to_linear(refcol.rgb),0);
+ frag_data[3] = vec4(0, 0, 0, 0);
+
+
+ //frag_data[0] = vec4(0.0,0,0,0);
+ //frag_data[1] = vec4(0, 1.0, 0.0, 0.0);
+ //frag_data[3] = vec4(0);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
index c65cf48c67..d485379a56 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
@@ -22,20 +22,21 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
+//class2/environment/waterF.glsl
#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
+out vec4 frag_color;
#else
-#define frag_data gl_FragData
+#define frag_color gl_FragColor
#endif
-uniform sampler2D bumpMap;
+vec3 scaleSoftClip(vec3 inColor);
+vec3 atmosTransport(vec3 inColor);
+
+uniform sampler2D bumpMap;
uniform sampler2D bumpMap2;
-uniform float blend_factor;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
@@ -51,49 +52,45 @@ uniform vec3 normScale;
uniform float fresnelScale;
uniform float fresnelOffset;
uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
+
//bigWave is (refCoord.w, view.w);
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec3 scaleSoftClip(vec3 c);
-vec2 encode_normal(vec3 n);
vec3 BlendNormal(vec3 bump1, vec3 bump2)
{
- //vec3 normal = bump1.xyz * vec3( 2.0, 2.0, 2.0) - vec3(1.0, 1.0, 0.0);
- //vec3 normal2 = bump2.xyz * vec3(-2.0, -2.0, 2.0) + vec3(1.0, 1.0, -1.0);
- //vec3 n = normalize(normal * dot(normal, normal2) - (normal2 * normal.z));
- vec3 n = normalize(mix(bump1, bump2, blend_factor));
+ vec3 n = mix(bump1, bump2, blend_factor);
return n;
}
+
void main()
{
vec4 color;
+
float dist = length(view.xy);
//normalize view vector
vec3 viewVec = normalize(view.xyz);
//get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+ vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
vec3 wave1 = BlendNormal(wave1_a, wave1_b);
vec3 wave2 = BlendNormal(wave2_a, wave2_b);
vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
//get base fresnel components
vec3 df = vec3(
@@ -130,6 +127,7 @@ void main()
refcol *= df1 * 0.333;
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+
wavef.z *= max(-viewVec.z, 0.1);
wavef = normalize(wavef);
@@ -140,7 +138,6 @@ void main()
vec2 refvec4 = distort+refdistort4/dmod;
float dweight = min(dist2*blurMultiplier, 1.0);
vec4 baseCol = texture2D(refTex, refvec4);
-
refcol = mix(baseCol*df2, refcol, dweight);
//get specular component
@@ -155,20 +152,19 @@ void main()
vec4 fb = texture2D(screenTex, distort2);
//mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
+ // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
-
- color.rgb *= 2.0f;
- color.rgb = scaleSoftClip(color.rgb);
+ color.rgb += spec * specular;
- vec4 pos = vary_position;
+ color.rgb = atmosTransport(color.rgb);
+ color.rgb = scaleSoftClip(color.rgb);
+ color.a = spec * sunAngle2;
- color.rgb += spec * specular;
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+ frag_color = color;
+
+#if defined(WATER_EDGE)
+ gl_FragDepth = 0.9999847f;
+#endif
- frag_data[0] = vec4(color.rgb, color); // diffuse
- frag_data[1] = vec4(spec * specular, spec); // speccolor, spec
- frag_data[2] = vec4(encode_normal(wavef.xyz), 0.05, 0);// normalxy, 0, 0
}
+
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index ee9c990b12..1463d507bc 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -29,8 +29,11 @@ vec3 scaleSoftClipFrag(vec3 light);
uniform int no_atmo;
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
+{
if (no_atmo == 1)
{
return light;
@@ -40,6 +43,11 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
return light * 2.0;
}
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten)
+{
+ return atmosFragLighting(light, additive, atten);
+}
+
vec3 atmosLighting(vec3 light)
{
return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
new file mode 100644
index 0000000000..c69eba93b6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
@@ -0,0 +1,251 @@
+/**
+ * @file class2\windlight\atmosphericsFuncs.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 sunlight_linear;
+uniform vec3 moonlight_color;
+uniform vec3 moonlight_linear;
+uniform int sun_up_factor;
+uniform vec3 ambient_color;
+uniform vec3 ambient_linear;
+uniform vec3 blue_horizon;
+uniform vec3 blue_horizon_linear;
+uniform vec3 blue_density;
+uniform vec3 blue_density_linear;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float haze_density_linear;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec3 glow;
+uniform float scene_light_strength;
+uniform mat3 ssao_effect_mat;
+uniform int no_atmo;
+uniform float sun_moon_glow_factor;
+
+float getAmbientClamp() { return 1.0f; }
+
+vec3 srgb_to_linear(vec3 col);
+
+// return colors in sRGB space
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten, bool use_ao)
+{
+ vec3 rel_pos = inPositionEye;
+
+ //(TERRAIN) limit altitude
+ if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
+
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+
+ // sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
+ // I had thought blue_density and haze_density should have equal weighting,
+ // but attenuation due to haze_density tends to seem too strong
+
+ vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = vec3(haze_density) / combined_haze;
+
+ //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
+ float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
+ sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
+
+ // main atmospheric scattering line integral
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
+
+ // final atmosphere attenuation factor
+ atten = combined_haze.rgb;
+
+ // compute haze glow
+ float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+
+ // dampen sun additive contrib when not facing it...
+ // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
+ // if (length(light_dir) > 0.01)
+ haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
+
+ haze_glow = 1. - haze_glow;
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // add "minimum anti-solar illumination"
+ haze_glow += .25;
+
+ haze_glow *= sun_moon_glow_factor;
+
+ vec3 amb_color = ambient_color;
+
+ // increase ambient when there are more clouds
+ vec3 tmpAmbient = amb_color + (vec3(1.) - amb_color) * cloud_shadow * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat,
+ * ambAlpha);
+ */
+ if (use_ao)
+ {
+ tmpAmbient = mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor);
+ }
+
+ // Similar/Shared Algorithms:
+ // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
+ // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
+ // haze color
+ vec3 cs = sunlight.rgb * (1. - cloud_shadow);
+ additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+
+ // brightness of surface both sunlight and ambient
+ sunlit = sunlight.rgb;
+ amblit = tmpAmbient.rgb;
+ additive *= vec3(1.0 - combined_haze);
+}
+
+
+vec3 srgb_to_linear(vec3 col);
+
+// provide a touch of lighting in the opposite direction of the sun light
+ // so areas in shadow don't lose all detail
+float ambientLighting(vec3 norm, vec3 light_dir)
+{
+ float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0);
+ ambient *= 0.56;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
+ return ambient;
+}
+
+
+// return colors in linear space
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten)
+{
+#if 1
+ calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false);
+ sunlit = srgb_to_linear(sunlit);
+ additive = srgb_to_linear(additive);
+ amblit = ambient_linear;
+
+ amblit *= ambientLighting(norm, light_dir);
+#else
+
+ //EXPERIMENTAL -- attempt to factor out srgb_to_linear conversions above
+ vec3 rel_pos = inPositionEye;
+
+ //(TERRAIN) limit altitude
+ if (abs(rel_pos.y) > max_y) rel_pos *= (max_y / rel_pos.y);
+
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+ vec3 sunlight = (sun_up_factor == 1) ? vec3(sunlight_linear, 0.0) : vec3(moonlight_linear, 0.0);
+
+ // sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
+ // I had thought blue_density and haze_density should have equal weighting,
+ // but attenuation due to haze_density tends to seem too strong
+
+ vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = vec3(haze_density) / combined_haze;
+
+ //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
+ float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
+ sunlight *= exp(-light_atten * above_horizon_factor); // for sun [horizon..overhead] this maps to an exp curve [0..1]
+
+ // main atmospheric scattering line integral
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist * distance_multiplier);
+
+ // final atmosphere attenuation factor
+ atten = combined_haze.rgb;
+
+ // compute haze glow
+ float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+
+ // dampen sun additive contrib when not facing it...
+ // SL-13539: This "if" clause causes an "additive" white artifact at roughly 77 degreees.
+ // if (length(light_dir) > 0.01)
+ haze_glow *= max(0.0f, dot(light_dir, rel_pos_norm));
+
+ haze_glow = 1. - haze_glow;
+ // haze_glow is 0 at the sun and increases away from sun
+ haze_glow = max(haze_glow, .001); // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ haze_glow *= glow.x;
+ // higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ haze_glow = pow(haze_glow, glow.z);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // add "minimum anti-solar illumination"
+ haze_glow += .25;
+
+ haze_glow *= sun_moon_glow_factor;
+
+ //vec3 amb_color = vec4(ambient_linear, 0.0);
+ vec3 amb_color = ambient_color;
+
+ // increase ambient when there are more clouds
+ vec3 tmpAmbient = amb_color + (vec3(1.) - amb_color) * cloud_shadow * 0.5;
+
+ // Similar/Shared Algorithms:
+ // indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
+ // indra\newview\app_settings\shaders\class1\windlight\atmosphericsFuncs.glsl -- calcAtmosphericVars()
+ // haze color
+ vec3 cs = sunlight.rgb * (1. - cloud_shadow);
+ additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
+
+ // brightness of surface both sunlight and ambient
+ sunlit = min(sunlight.rgb, vec3(1));
+ amblit = tmpAmbient.rgb;
+ additive *= vec3(1.0 - combined_haze);
+
+ //sunlit = sunlight_linear;
+ amblit = ambient_linear*0.8;
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index fa928d993e..9c5a4903d0 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -35,15 +35,15 @@ out vec4 frag_color;
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
+uniform vec3 cloud_pos_density1;
+uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
@@ -70,8 +70,8 @@ void main()
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ vec3 cloudColorSun = vary_CloudColorSun;
+ vec3 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
@@ -120,7 +120,7 @@ void main()
alpha2 = 1. - alpha2 * alpha2;
// Combine
- vec4 color;
+ vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index 97ffa9feef..650009d393 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -33,8 +33,8 @@ ATTRIBUTE vec2 texcoord0;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
+VARYING vec3 vary_CloudColorSun;
+VARYING vec3 vary_CloudColorAmbient;
VARYING float vary_CloudDensity;
VARYING vec2 vary_texcoord0;
@@ -46,13 +46,13 @@ VARYING float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -60,10 +60,10 @@ uniform float cloud_shadow;
uniform float density_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
uniform float cloud_scale;
@@ -114,17 +114,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
+ vec3 sunlight = sunlight_color;
+ vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -155,14 +155,14 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
+ vec3 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow);
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
@@ -178,7 +178,7 @@ void main()
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= combined_haze;
vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 68db7fcbb1..a32a572461 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
@@ -28,6 +28,21 @@ uniform int no_atmo;
vec3 getAtmosAttenuation();
vec3 getAdditiveColor();
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
+vec3 scaleSoftClipFragLinear(vec3 light)
+{ // identical to non-linear version and that's probably close enough
+ if (no_atmo == 1)
+ {
+ return light;
+ }
+ //soft clip effect:
+ light = 1. - clamp(light, vec3(0.), vec3(1.));
+ light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
+ return light;
+}
+
vec3 scaleSoftClipFrag(vec3 light)
{
if (no_atmo == 1)
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index 7146349453..7a229e0f5e 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -33,7 +33,7 @@ out vec4 frag_color;
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
@@ -45,7 +45,7 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec4 color;
+ vec3 color;
color = vary_HazeColor;
color.rgb *= 2.;
/// Gamma correct for WL (soft clip effect).
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index a0a33b8642..8f7726bb0b 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -32,18 +32,18 @@ ATTRIBUTE vec3 position;
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_HazeColor;
+VARYING vec3 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -52,11 +52,9 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
-
void main()
{
// World / view / projection
@@ -83,17 +81,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec4 light_atten;
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -121,21 +119,21 @@ void main()
// For sun, add to glow. For moon, remove glow entirely. SL-13768
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
- vec4 color =
+ vec3 color =
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 tmpAmbient = ambient_color;
+ tmpAmbient += max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index b53a2e237f..ecf0430a88 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -32,6 +32,9 @@ vec3 getAtmosAttenuation();
uniform int no_atmo;
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
light *= atten.r;
@@ -44,6 +47,13 @@ vec3 atmosTransport(vec3 light)
return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten)
+{
+ // same as non-linear version, probably fine
+ float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
+ return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
+}
+
vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
deleted file mode 100644
index df9704ec25..0000000000
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * @file avatarV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 clothing;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec4 color;
-
-uniform vec4 gWindDir;
-uniform vec4 gSinWaveParams;
-uniform vec4 gGravity;
-
-const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542); // #minimax-generated coefficients
-const vec4 gPiConstants = vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); // # {1/2PI, 2PI, PI, PI/2}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- mat4 trans = getSkinnedTransform();
-
- vec3 norm;
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- //wind
- vec4 windEffect;
- windEffect = vec4(dot(norm, gWindDir.xyz));
- pos.x = dot(trans[2].xyz, position.xyz);
- windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
- + windEffect.xyz;
- windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3]
- windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength
-
- windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
- +vec3(gSinWaveParams.w); // use sin wave params to scale and offset input
-
-
- //reduce to period of 2 PI
- vec4 temp1, temp0, temp2, offsetPos;
- temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1]
- temp0.y = mod(temp1.x,1.0);
- windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2
- temp0.y = mod(temp1.z,1.0);
-
- windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI]
-
-
- //calculate sinusoid
- vec4 sinWave;
- temp1 = windEffect*windEffect;
- sinWave = -temp1 * gMinMaxConstants.w
- + vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
- sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
-
- // sinWave.x holds sin(norm . wind_direction) with primary frequency
- // sinWave.y holds sin(norm . wind_direction) with secondary frequency
- // sinWave.z hold cos(norm . wind_direction) with primary frequency
- sinWave.xyz = sinWave.xyz * gWindDir.w
- + vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind]
-
- // add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
- temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity?
- temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2]
- temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3]
- sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency)
- sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage
-
- sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape
- offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement
- temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation
- offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+vec4(position.xyz, 1.0); // add to offset vertex position, and zero out effect from w
- norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated)
-
- //add "backlighting" effect
- float colorAcc;
- colorAcc = 1.0 - clothing.w;
- norm.z -= colorAcc * 0.2;
-
- //renormalize normal (again)
- norm = normalize(norm);
-
- pos.x = dot(trans[0], offsetPos);
- pos.y = dot(trans[1], offsetPos);
- pos.z = dot(trans[2], offsetPos);
- pos.w = 1.0;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = calcLighting(pos.xyz, norm, color);
- vertex_color = col;
-
- gl_Position = projection_matrix * pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
deleted file mode 100644
index d973326f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file avatarShadowF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
deleted file mode 100644
index 1a655e6467..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file attachmentShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-
-VARYING vec4 pos;
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- pos = (mat*vec4(position.xyz, 1.0));
- pos = projection_matrix * vec4(pos.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- pos.z = max(pos.z, -pos.w+0.01);
-#endif
- gl_Position = pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
deleted file mode 100644
index 48eefc7a73..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @file avatarShadowF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
deleted file mode 100644
index 164b355f20..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file avatarShadowV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-
-mat4 getSkinnedTransform();
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-void main()
-{
- vec3 norm;
-
- vec4 pos_in = vec4(position.xyz, 1.0);
- mat4 trans = getSkinnedTransform();
-
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- pos = projection_matrix * pos;
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
deleted file mode 100644
index 32210f60dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-vec4 computeMoments(float depth, float alpha);
-
-void main()
-{
- if (cloud_scale >= 0.001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = computeMoments(length(pos), alpha1);
- }
- else
- {
- frag_color = vec4(0);
- }
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
deleted file mode 100644
index e40d7e7c75..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return cloud_noise_sample;
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale < 0.001)
- {
- discard;
- }
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- vec3 view_ray = vary_pos.xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 1.0 - alpha1, sun_direction, transmittance);
-
- vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001);
-
- // Combine
- vec4 color;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
-
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
-
- vec3 sun_indir = vec3(-view_direction.xy, view_direction.z);
- vec3 amb = vec3(dot(l1r, l1tap * vec4(1, sun_indir)),
- dot(l1g, l1tap * vec4(1, sun_indir)),
- dot(l1b, l1tap * vec4(1, sun_indir)));
-
-
- amb = max(vec3(0), amb);
-
- color.rgb = sun_color * cloud_color.rgb * (1. - alpha2);
- color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
- color.rgb += amb;
-
- frag_data[0] = vec4(color.rgb, alpha1);
- frag_data[1] = vec4(0);
- frag_data[2] = vec4(0,1,0,1);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
deleted file mode 100644
index 71e422ddf0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file WLCloudsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-uniform mat4 modelview_projection_matrix;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-//////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-// Output parameters
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-// Inputs
-uniform float cloud_scale;
-uniform vec4 lightnorm;
-uniform vec3 camPosLocal;
-
-void main()
-{
- vary_pos = position;
-
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Texture coords
- vary_texcoord0 = texcoord0;
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= max(0.001, cloud_scale);
- vary_texcoord0.xy += 0.5;
-
- vary_texcoord1 = vary_texcoord0;
- vary_texcoord1.x += lightnorm.x * 0.0125;
- vary_texcoord1.y += lightnorm.z * 0.0125;
-
- vary_texcoord2 = vary_texcoord0 * 16.;
- vary_texcoord3 = vary_texcoord1 * 16.;
-
- // END CLOUDS
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
deleted file mode 100644
index e27bbce094..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file class1/deferred/deferredUtil.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec2 getScreenCoordinate(vec2 screenpos)
-{
- vec2 sc = screenpos.xy * 2.0;
- if (screen_res.x > 0 && screen_res.y > 0)
- {
- sc /= screen_res;
- }
- return sc - vec2(1.0, 1.0);
-}
-
-vec3 getNorm(vec2 screenpos)
-{
- vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-float getDepth(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen).r;
- return depth;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = getDepth(pos_screen);
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getPositionWithDepth(vec2 pos_screen, float depth)
-{
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
deleted file mode 100644
index cdaff4b09f..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file depthToShadowVolumeG.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-#extension GL_ARB_geometry_shader4 : enable
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-layout (triangles) in;
-layout (triangle_strip, max_vertices = 128) out;
-
-uniform sampler2DRect depthMap;
-uniform mat4 shadowMatrix[6];
-uniform vec4 lightpos;
-
-VARYING vec2 vary_texcoord0;
-
-out vec3 to_vec;
-
-void cross_products(out vec4 ns[3], int a, int b, int c)
-{
- ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz);
- ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz);
- ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz);
-}
-
-vec3 getLightDirection(vec4 lightpos, vec3 pos)
-{
-
- vec3 lightdir = lightpos.xyz - lightpos.w * pos;
- return lightdir;
-}
-
-void emitTri(vec4 v[3])
-{
- gl_Position = proj_matrix * v[0];
- EmitVertex();
-
- gl_Position = proj_matrix * v[1];
- EmitVertex();
-
- gl_Position = proj_matrix * v[2];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitQuad(vec4 v[4]
-{
- // Emit a quad as a triangle strip.
- gl_Position = proj_matrix*v[0];
- EmitVertex();
-
- gl_Position = proj_matrix*v[1];
- EmitVertex();
-
- gl_Position = proj_matrix*v[2];
- EmitVertex();
-
- gl_Position = proj_matrix*v[3];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitPrimitives(int layer)
-{
- int i = layer;
- gl_Layer = i;
-
- vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg));
- vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg));
- vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg));
- vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg));
-
- depth1 = min(depth1, depth2);
- depth1 = min(depth1, depth3);
- depth1 = min(depth1, depth4);
-
- vec2 depth = min(depth1.xy, depth1.zw);
-
- int side = sqrt(gl_VerticesIn);
-
- for (int j = 0; j < side; j++)
- {
- for (int k = 0; k < side; ++k)
- {
- vec3 pos = gl_PositionIn[(j * side) + k].xyz;
- vec4 v = shadowMatrix[i] * vec4(pos, 1.0);
- gl_Position = v;
- to_vec = pos - light_position.xyz * depth;
- EmitVertex();
- }
-
- EndPrimitive();
- }
-
- vec3 norms[3]; // Normals
- vec3 lightdir3]; // Directions toward light
-
- vec4 v[4]; // Temporary vertices
-
- vec4 or_pos[3] =
- { // Triangle oriented toward light source
- gl_PositionIn[0],
- gl_PositionIn[2],
- gl_PositionIn[4]
- };
-
- // Compute normal at each vertex.
- cross_products(n, 0, 2, 4);
-
- // Compute direction from vertices to light.
- lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz);
- lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz);
- lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz);
-
- // Check if the main triangle faces the light.
- bool faces_light = true;
- if (!(dot(ns[0],d[0]) > 0
- |dot(ns[1],d[1]) > 0
- |dot(ns[2],d[2]) > 0))
- {
- // Flip vertex winding order in or_pos.
- or_pos[1] = gl_PositionIn[4];
- or_pos[2] = gl_PositionIn[2];
- faces_light = false;
- }
-
- // Near cap: simply render triangle.
- emitTri(or_pos);
-
- // Far cap: extrude positions to infinity.
- v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0);
- v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0);
- v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0);
-
- emitTri(v);
-
- // Loop over all edges and extrude if needed.
- for ( int i=0; i<3; i++ )
- {
- // Compute indices of neighbor triangle.
- int v0 = i*2;
- int nb = (i*2+1);
- int v1 = (i*2+2) % 6;
- cross_products(n, v0, nb, v1);
-
- // Compute direction to light, again as above.
- d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz;
- d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz;
- d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz;
-
- bool is_parallel = gl_PositionIn[nb].w < 1e-5;
-
- // Extrude the edge if it does not have a
- // neighbor, or if it's a possible silhouette.
- if (is_parallel ||
- ( faces_light != (dot(ns[0],d[0])>0 ||
- dot(ns[1],d[1])>0 ||
- dot(ns[2],d[2])>0) ))
- {
- // Make sure sides are oriented correctly.
- int i0 = faces_light ? v0 : v1;
- int i1 = faces_light ? v1 : v0;
-
- v[0] = gl_PositionIn[i0];
- v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0);
- v[2] = gl_PositionIn[i1];
- v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0);
-
- emitQuad(v);
- }
- }
-}
-
-void main()
-{
- // Output
- emitPrimitives(0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..c0a1491446
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -0,0 +1,106 @@
+/**
+ * @file fullbrightShinyF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifndef HAS_DIFFUSE_LOOKUP
+uniform sampler2D diffuseMap;
+#endif
+
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+VARYING vec3 vary_position;
+
+uniform samplerCube environmentMap;
+
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+// reflection probe interface
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+// See:
+// class1\deferred\fullbrightShinyF.glsl
+// class1\lighting\lightFullbrightShinyF.glsl
+void main()
+{
+#ifdef HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+#endif
+
+ color.rgb *= vertex_color.rgb;
+
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ vec3 pos = vary_position;
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
+
+ float env_intensity = vertex_color.a;
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ vec3 norm = normalize(vary_texcoord1.xyz);
+ vec4 spec = vec4(0,0,0,0);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, env_intensity);
+ applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
+
+ color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
+
+ color.a = 1.0;
+
+ color.rgb = srgb_to_linear(color.rgb);
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
deleted file mode 100644
index 34d26cddea..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file class3/deferred/gatherSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec2 screen_res;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-void main()
-{
- vec2 offset = vec2(2.0) / screen_res;
-
- vec4 r = vec4(0);
- vec4 g = vec4(0);
- vec4 b = vec4(0);
-
- vec2 tc = vary_frag * 2.0;
-
- r += texture2D(sh_input_r, tc + vec2(0, 0));
- r += texture2D(sh_input_r, tc + vec2(offset.x, 0));
- r += texture2D(sh_input_r, tc + vec2(0, offset.y));
- r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y));
- r /= 4.0f;
-
- g += texture2D(sh_input_g, tc + vec2(0, 0));
- g += texture2D(sh_input_g, tc + vec2(offset.x, 0));
- g += texture2D(sh_input_g, tc + vec2(0, offset.y));
- g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y));
- g /= 4.0f;
-
- b += texture2D(sh_input_b, tc + vec2(0, 0));
- b += texture2D(sh_input_b, tc + vec2(offset.x, 0));
- b += texture2D(sh_input_b, tc + vec2(0, offset.y));
- b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y));
- b /= 4.0f;
-
- frag_data[0] = r;
- frag_data[1] = g;
- frag_data[2] = b;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
deleted file mode 100644
index 337c8a50fe..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file gatherSkyShV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_frag;
-uniform vec2 screen_res;
-
-void main()
-{
- // pass through untransformed fullscreen pos
- float oo_divisor = screen_res.x / 64.0;
- vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0);
- gl_Position = vec4(pos.xyz, 1.0);
- vary_frag = texcoord0 * oo_divisor;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
deleted file mode 100644
index d5d91c88f0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file class3/deferred/genSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec3 sun_dir;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 calcDirection(vec2 tc)
-{
- float phi = tc.y * 2.0 * 3.14159265;
- float cosTheta = sqrt(1.0 - tc.x);
- float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
- return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
-}
-
-// reverse mapping above to convert a hemisphere direction into phi/theta values
-void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta)
-{
- float sin_theta;
- float cos_theta;
- cos_theta = dir.z;
- theta = acos(cos_theta);
- sin_theta = sin(theta);
- phi = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0;
-}
-
-// reverse mapping above to convert a hemisphere direction into an SH texture sample pos
-vec2 calcShUvFromDirection(vec3 dir)
-{
- vec2 uv;
- float phi;
- float theta;
- getPhiAndThetaFromDirection(dir, phi, theta);
- uv.y = phi / 2.0 * 3.14159265;
- uv.x = theta / 2.0 * 3.14159265;
- return uv;
-}
-
-void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3])
-{
- coeffs[0] = vec4(basis.x, n * basis.yzw * c.r);
- coeffs[1] = vec4(basis.x, n * basis.yzw * c.g);
- coeffs[2] = vec4(basis.x, n * basis.yzw * c.b);
-}
-
-void main()
-{
- float Y00 = sqrt(1.0 / 3.14159265) * 0.5;
- float Y1x = sqrt(3.0 / 3.14159265) * 0.5;
- float Y1y = Y1x;
- float Y1z = Y1x;
-
- vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z);
-
- vec3 view_direction = calcDirection(vary_frag);
- vec3 sun_direction = normalize(sun_dir);
- vec3 cam_pos = vec3(0, 0, 6360);
-
- vec3 transmittance;
- vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance);
-
- vec3 color = vec3(1.0) - exp(-radiance * 0.0001);
-
- color = pow(color, vec3(1.0/2.2));
-
- vec4 coeffs[3];
- coeffs[0] = vec4(0);
- coeffs[1] = vec4(0);
- coeffs[2] = vec4(0);
-
- projectToL1(view_direction, color.rgb, L1, coeffs);
-
- frag_data[0] = coeffs[0];
- frag_data[1] = coeffs[1];
- frag_data[2] = coeffs[2];
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
deleted file mode 100644
index 33c5667cae..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file class3/deferred/indirect.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetIndirect(vec3 norm)
-{
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
- indirect = clamp(indirect, vec3(0), vec3(1.0));
- return indirect;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
new file mode 100644
index 0000000000..8016022d78
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -0,0 +1,380 @@
+/**
+* @file materialF.glsl
+*
+* $LicenseInfo:firstyear=2007&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2007, 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$
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+//class1/deferred/materialF.glsl
+
+// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+
+#define DIFFUSE_ALPHA_MODE_NONE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
+uniform int sun_up_factor;
+
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten);
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cs);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+uniform mat3 env_mat;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+VARYING vec2 vary_fragcoord;
+
+VARYING vec3 vary_position;
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+float getAmbientClamp();
+void waterClip(vec3 pos);
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz - v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ dist /= inverted_la;
+
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0f;
+
+ if (dist_atten <= 0.0)
+ {
+ return col;
+ }
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= dot(n, lv);
+
+ float lit = 0.0f;
+
+ float amb_da = ambiance;
+ if (da >= 0)
+ {
+ lit = max(da * dist_atten, 0.0);
+ col = lit * light_col * diffuse;
+ amb_da += (da*0.5 + 0.5) * ambiance;
+ }
+ amb_da += (da*da*0.5 + 0.5) * ambiance;
+ amb_da *= dist_atten;
+ amb_da = min(amb_da, 1.0f - lit);
+
+ // SL-10969 need to see why these are blown out
+ //col.rgb += amb_da * light_col * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv + npos);
+ float nh = dot(n, h);
+ float nv = dot(n, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
+ vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
+ }
+ }
+ }
+
+ return max(col, vec3(0.0, 0.0, 0.0));
+}
+
+#else
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+#endif
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+#ifdef HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+uniform sampler2D specularMap;
+
+VARYING vec2 vary_texcoord2;
+#endif
+
+uniform float env_intensity;
+uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+uniform float minimum_alpha;
+#endif
+
+#ifdef HAS_NORMAL_MAP
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec2 encode_normal(vec3 n);
+
+void main()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ waterClip(vary_position.xyz);
+#endif
+
+ vec2 pos_screen = vary_texcoord0.xy;
+
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+
+ // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
+ float bias = 0.001953125; // 1/512, or half an 8-bit quantization
+ if (diffcol.a < minimum_alpha-bias)
+ {
+ discard;
+ }
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+ vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+ spec.rgb *= specular_color.rgb;
+#else
+ vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+
+#ifdef HAS_NORMAL_MAP
+ vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+
+ norm.xyz = norm.xyz * 2 - 1;
+
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+#else
+ vec4 norm = vec4(0,0,0,1.0);
+ vec3 tnorm = vary_normal;
+#endif
+
+ norm.xyz = normalize(tnorm.xyz);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+
+ vec4 final_color = diffcol;
+
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+ final_color.a = emissive_brightness;
+#else
+ final_color.a = max(final_color.a, emissive_brightness);
+#endif
+
+ vec4 final_specular = spec;
+
+#ifdef HAS_SPECULAR_MAP
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, GBUFFER_FLAG_HAS_ATMOS);
+ final_specular.a = specular_color.a * norm.a;
+#else
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, GBUFFER_FLAG_HAS_ATMOS);
+ final_specular.a = specular_color.a;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ //forward rendering, output lit linear color
+ diffcol.rgb = srgb_to_linear(diffcol.rgb);
+ final_specular.rgb = srgb_to_linear(final_specular.rgb);
+
+ vec3 pos = vary_position;
+
+ float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
+#endif
+
+ vec4 diffuse = final_color;
+
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+ float bloom = 0.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, final_specular.a, env_intensity);
+
+ // use sky settings ambient or irradiance map sample, whichever is brighter
+ color = max(amblit, ambenv);
+
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ vec3 sun_contrib = min(da, shadow) * sunlit;
+ color.rgb += sun_contrib;
+ color *= diffcol.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ if (final_specular.a > 0.0) // specular reflection
+ {
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, final_specular.a)).r);
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * final_specular.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+
+ color += spec_contrib;
+
+ applyGlossEnv(color, glossenv, final_specular, pos.xyz, norm.xyz);
+ }
+
+ color = mix(color.rgb, diffcol.rgb, diffuse.a);
+
+ if (env_intensity > 0.0)
+ { // add environmentmap
+ applyLegacyEnv(color, legacyenv, final_specular, pos.xyz, norm.xyz, env_intensity);
+ }
+
+ color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), diffuse.a);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogView(pos, vec4(color, 0.0));
+ color = temp.rgb;
+#endif
+
+ vec3 npos = normalize(-pos.xyz);
+ vec3 light = vec3(0, 0, 0);
+
+#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color += light;
+
+ float al = diffcol.a*vertex_color.a;
+
+ frag_color = vec4(color, al);
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
+
+ // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+ frag_data[0] = final_color; // gbuffer is sRGB for legacy materials
+ frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
new file mode 100644
index 0000000000..6dd446d9f7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -0,0 +1,195 @@
+/**
+ * @file class3\deferred\multiPointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect depthMap;
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D noiseMap;
+uniform sampler2D lightFunc;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+uniform int light_count;
+uniform vec4 light[LIGHT_COUNT]; // .w = size; see C++ fullscreen_lights.push_back()
+uniform vec4 light_col[LIGHT_COUNT]; // .a = falloff
+
+uniform vec2 screen_res;
+uniform float far_z;
+uniform mat4 inv_proj;
+
+VARYING vec4 vary_fragcoord;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getPosition(vec2 pos_screen);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+
+// Util
+vec3 hue_to_rgb(float hue);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void main()
+{
+#if defined(LOCAL_LIGHT_KILL)
+ discard; // Bail immediately
+#else
+ vec3 final_color = vec3(0, 0, 0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+ if (pos.z < far_z)
+ {
+ discard;
+ }
+
+ float envIntensity; // not used for this shader
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+
+ vec3 h, l, v = -normalize(pos);
+ float nh, nv, vh, lightDist;
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx)
+ {
+ vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
+ float falloff = light_col[ light_idx ].a;
+ float lightSize = light[ light_idx ].w;
+ vec3 lv = light[ light_idx ].xyz - pos;
+
+ lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ vec3 intensity = dist_atten * lightColor * 3.0;
+
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+ }
+ }
+ else
+ {
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
+ for (int i = 0; i < LIGHT_COUNT; ++i)
+ {
+ vec3 lv = light[i].xyz - pos;
+ float dist = length(lv);
+ dist /= light[i].w;
+ if (dist <= 1.0)
+ {
+ float nl = dot(n, lv);
+ if (nl > 0.0)
+ {
+ float lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ float fa = light_col[i].a;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, fa);
+ dist_atten *= noise;
+
+ float lit = nl * dist_atten;
+
+ vec3 col = light_col[i].rgb * lit * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl * 6.0, 1.0) * dist_atten;
+ float fres = pow(1 - vh, 5) * 0.4 + 0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * nl);
+ col += lit * scol * light_col[i].rgb * spec.rgb;
+ }
+ }
+
+ final_color += col;
+ }
+ }
+ }
+ }
+
+ frag_color.rgb = final_color;
+ frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
+
+#ifdef IS_AMD_CARD
+ // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage
+ // away which leads to unfun crashes and artifacts.
+ vec4 dummy1 = light[0];
+ vec4 dummy2 = light_col[0];
+ vec4 dummy3 = light[LIGHT_COUNT - 1];
+ vec4 dummy4 = light_col[LIGHT_COUNT - 1];
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
index 9d872b8df8..ad6a0fa752 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/softenLightV.glsl
+ * @file class3\deferred\multiPointLightV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,17 +22,18 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
uniform mat4 modelview_projection_matrix;
-uniform vec2 screen_res;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec4 vary_fragcoord;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vary_fragcoord = pos;
+
+ gl_Position = pos;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index 9d62b9d180..cb8877ebe5 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -1,9 +1,9 @@
/**
- * @file multiSpotLightF.glsl
+ * @file class3\deferred\multiSpotLightF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,10 +38,11 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
+uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
@@ -61,6 +62,7 @@ uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
+// Light params
uniform vec3 center;
uniform float size;
uniform vec3 color;
@@ -71,221 +73,198 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec3 colorized_dot(float x);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 cs);
+vec4 texture2DLodSpecular(vec2 tc, float lod);
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+vec4 getPosition(vec2 pos_screen);
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
+const float M_PI = 3.14159265;
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+void main()
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-
-vec4 getPosition(vec2 pos_screen);
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ vec3 final_color = vec3(0,0,0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
-void main()
-{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
+ vec3 lv;
+ vec4 proj_tc;
+ float dist, l_dist;
+ if (clipProjectedLightVars(center, pos, dist, l_dist, lv, proj_tc))
{
discard;
}
-
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ vec4 shd = texture2DRect(lightMap, tc);
+ shadow = (proj_shadow_idx==0)?shd.b:shd.a;
shadow += shadow_fade;
shadow = clamp(shadow, 0.0, 1.0);
}
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5)+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity);
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
{
discard;
}
-
+
lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
- vec3 col = vec3(0,0,0);
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 dlit = vec3(0, 0, 0);
+ vec3 slit = vec3(0, 0, 0);
+
+ vec3 amb_rgb = vec3(0);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
- vec3 dlit = vec3(0, 0, 0);
+ // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
+ if (proj_tc.x > 0.0 && proj_tc.x < 1.0
+ && proj_tc.y > 0.0 && proj_tc.y < 1.0)
+ {
+ float lit = 0.0;
+ float amb_da = 0.0;
+
+ if (nl > 0.0)
+ {
+ amb_da += (nl*0.5 + 0.5) * proj_ambiance;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
+ }
+ }
+ else
{
- float amb_da = proj_ambiance;
- float lit = 0.0;
- if (da > 0.0)
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
{
- lit = da * dist_atten * noise;
+ float amb_da = 0;
+ float lit = 0.0;
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+ if (nl > 0.0)
+ {
+ lit = nl * dist_atten * noise;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ final_color = dlit*lit*diffuse*shadow;
+
+ // unshadowed for consistency between forward and deferred?
+ amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
}
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
+ if (spec.a > 0.0)
+ {
+ dlit *= min(nl*6.0, 1.0) * dist_atten;
- if (spec.a > 0.0)
- {
- vec3 npos = -normalize(pos);
- dlit *= min(da*6.0, 1.0) * dist_atten;
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+ float fres = pow(1 - vh, 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
- //col += spec.rgb;
- }
- }
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ final_color += speccol;
+ }
+ }
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), n);
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
+ if (stc.z > 0.0)
{
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
}
}
}
}
//not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
-
- col = scaleDownLight(col);
+ final_color = max(final_color, vec3(0.0));
- //output linear space color as gamma correction happens down stream
- frag_color.rgb = col;
+ //output linear
+ frag_color.rgb = final_color;
frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
new file mode 100644
index 0000000000..cdffcf103d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -0,0 +1,156 @@
+/**
+ * @file class3\deferred\pointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D noiseMap;
+uniform sampler2D lightFunc;
+uniform sampler2DRect depthMap;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+
+// light params
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
+
+VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
+uniform vec2 screen_res;
+
+uniform mat4 inv_proj;
+uniform vec4 viewport;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getPosition(vec2 pos_screen);
+vec2 getScreenXY(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+void main()
+{
+ vec3 final_color = vec3(0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+
+ // Common half vectors calcs
+ vec3 lv = trans_center.xyz-pos;
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ if (lightDist >= size)
+ {
+ discard;
+ }
+ float dist = lightDist / size;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
+ else
+ {
+ if (nl < 0.0)
+ {
+ discard;
+ }
+
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ float lit = nl * dist_atten * noise;
+
+ final_color = color.rgb*lit*diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl*6.0, 1.0) * dist_atten;
+
+ float sa = nh;
+ float fres = pow(1 - vh, 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ final_color += lit*scol*color.rgb*spec.rgb;
+ }
+ }
+
+ if (dot(final_color, final_color) <= 0.0)
+ {
+ discard;
+ }
+ }
+
+ frag_color.rgb = final_color;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
index db8c75fb8a..d42c8f6cf6 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shadowCubeV.glsl
+ * @file class3\deferred\pointLightV.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,27 +24,22 @@
*/
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
+uniform vec3 center;
+uniform float size;
-uniform vec3 box_center;
-uniform vec3 box_size;
+VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
void main()
{
//transform vertex
- vec3 p = position*box_size+box_center;
- vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
+ vec3 p = position*size+center;
+ vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
+ vary_fragcoord = pos;
+ trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..ca436033f1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -0,0 +1,572 @@
+/**
+ * @file class3/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#define FLT_MAX 3.402823466e+38
+
+#define REFMAP_COUNT 256
+#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
+
+uniform samplerCubeArray reflectionProbes;
+uniform samplerCubeArray irradianceProbes;
+
+layout (std140) uniform ReflectionProbes
+{
+ // list of OBBs for user override probes
+ // box is a set of 3 planes outward facing planes and the depth of the box along that plane
+ // for each box refBox[i]...
+ /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
+ // box[3][0..2] - plane thickness
+ mat4 refBox[REFMAP_COUNT];
+ // list of bounding spheres for reflection probes sorted by distance to camera (closest first)
+ vec4 refSphere[REFMAP_COUNT];
+ // extra parameters (currently only .x used for probe ambiance)
+ vec4 refParams[REFMAP_COUNT];
+ // index of cube map in reflectionProbes for a corresponding reflection probe
+ // e.g. cube map channel of refSphere[2] is stored in refIndex[2]
+ // refIndex.x - cubemap channel in reflectionProbes
+ // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index)
+ // refIndex.z - number of neighbors
+ // refIndex.w - priority, if negative, this probe has a box influence
+ ivec4 refIndex[REFMAP_COUNT];
+
+ // neighbor list data (refSphere indices, not cubemap array layer)
+ ivec4 refNeighbor[1024];
+
+ // number of reflection probes present in refSphere
+ int refmapCount;
+};
+
+// Inputs
+uniform mat3 env_mat;
+
+// list of probeIndexes shader will actually use after "getRefIndex" is called
+// (stores refIndex/refSphere indices, NOT rerflectionProbes layer)
+int probeIndex[REF_SAMPLE_COUNT];
+
+// number of probes stored in probeIndex
+int probeInfluences = 0;
+
+bool isAbove(vec3 pos, vec4 plane)
+{
+ return (dot(plane.xyz, pos) + plane.w) > 0;
+}
+
+int max_priority = 0;
+
+// return true if probe at index i influences position pos
+bool shouldSampleProbe(int i, vec3 pos)
+{
+ if (refIndex[i].w < 0)
+ {
+ vec4 v = refBox[i] * vec4(pos, 1.0);
+ if (abs(v.x) > 1 ||
+ abs(v.y) > 1 ||
+ abs(v.z) > 1)
+ {
+ return false;
+ }
+
+ max_priority = max(max_priority, -refIndex[i].w);
+ }
+ else
+ {
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d = dot(delta, delta);
+ float r2 = refSphere[i].w;
+ r2 *= r2;
+
+ if (d > r2)
+ { //outside bounding sphere
+ return false;
+ }
+
+ max_priority = max(max_priority, refIndex[i].w);
+ }
+
+ return true;
+}
+
+// call before sampleRef
+// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
+// overall algorithm --
+void preProbeSample(vec3 pos)
+{
+ // TODO: make some sort of structure that reduces the number of distance checks
+ for (int i = 1; i < refmapCount; ++i)
+ {
+ // found an influencing probe
+ if (shouldSampleProbe(i, pos))
+ {
+ probeIndex[probeInfluences] = i;
+ ++probeInfluences;
+
+ int neighborIdx = refIndex[i].y;
+ if (neighborIdx != -1)
+ {
+ int neighborCount = min(refIndex[i].z, REF_SAMPLE_COUNT-1);
+
+ int count = 0;
+ while (count < neighborCount)
+ {
+ // check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index)
+
+ int idx = refNeighbor[neighborIdx].x;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].y;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].z;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ idx = refNeighbor[neighborIdx].w;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ return;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ return;
+ }
+
+ ++neighborIdx;
+ }
+
+ return;
+ }
+ }
+ }
+
+ if (probeInfluences == 0)
+ { // probe at index 0 is a special fallback probe
+ probeIndex[0] = 0;
+ probeInfluences = 1;
+ }
+}
+
+// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+
+// original reference implementation:
+/*
+bool intersect(const Ray &ray) const
+{
+ float t0, t1; // solutions for t if the ray intersects
+#if 0
+ // geometric solution
+ Vec3f L = center - orig;
+ float tca = L.dotProduct(dir);
+ // if (tca < 0) return false;
+ float d2 = L.dotProduct(L) - tca * tca;
+ if (d2 > radius2) return false;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+#else
+ // analytic solution
+ Vec3f L = orig - center;
+ float a = dir.dotProduct(dir);
+ float b = 2 * dir.dotProduct(L);
+ float c = L.dotProduct(L) - radius2;
+ if (!solveQuadratic(a, b, c, t0, t1)) return false;
+#endif
+ if (t0 > t1) std::swap(t0, t1);
+
+ if (t0 < 0) {
+ t0 = t1; // if t0 is negative, let's use t1 instead
+ if (t0 < 0) return false; // both t0 and t1 are negative
+ }
+
+ t = t0;
+
+ return true;
+} */
+
+// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
+vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
+{
+ float t0, t1; // solutions for t if the ray intersects
+
+ vec3 L = center - origin;
+ float tca = dot(L,dir);
+
+ float d2 = dot(L,L) - tca * tca;
+
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+
+ vec3 v = origin + dir * t1;
+ return v;
+}
+
+// from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+/*
+vec3 DirectionWS = normalize(PositionWS - CameraWS);
+vec3 ReflDirectionWS = reflect(DirectionWS, NormalWS);
+
+// Intersection with OBB convertto unit box space
+// Transform in local unit parallax cube space (scaled and rotated)
+vec3 RayLS = MulMatrix( float(3x3)WorldToLocal, ReflDirectionWS);
+vec3 PositionLS = MulMatrix( WorldToLocal, PositionWS);
+
+vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+// Use Distance in WS directly to recover intersection
+vec3 IntersectPositionWS = PositionWS + ReflDirectionWS * Distance;
+vec3 ReflDirectionWS = IntersectPositionWS - CubemapPositionWS;
+
+return texCUBE(envMap, ReflDirectionWS);
+*/
+
+// get point of intersection with given probe's box influence volume
+// origin - ray origin in clip space
+// dir - ray direction in clip space
+// i - probe index in refBox/refSphere
+vec3 boxIntersect(vec3 origin, vec3 dir, int i)
+{
+ // Intersection with OBB convertto unit box space
+ // Transform in local unit parallax cube space (scaled and rotated)
+ mat4 clipToLocal = refBox[i];
+
+ vec3 RayLS = mat3(clipToLocal) * dir;
+ vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
+
+ vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+ vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+ vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+ vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+ float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+ // Use Distance in CS directly to recover intersection
+ vec3 IntersectPositionCS = origin + dir * Distance;
+
+ return IntersectPositionCS;
+}
+
+
+
+// Tap a reflection probe
+// pos - position of pixel
+// dir - pixel normal
+// vi - return value of intersection point with influence volume
+// wi - return value of approximate world space position of sampled pixel
+// lod - which mip to bias towards (lower is higher res, sharper reflections)
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out vec3 vi, out vec3 wi, float lod, vec3 c, int i)
+{
+ //lod = max(lod, 1);
+ // parallax adjustment
+
+ vec3 v;
+
+ if (refIndex[i].w < 0)
+ {
+ v = boxIntersect(pos, dir, i);
+ w = 1.0;
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+ float rr = r * r; // radius squared
+
+ v = sphereIntersect(pos, dir, c, rr);
+
+ float p = float(abs(refIndex[i].w)); // priority
+
+ float r1 = r * 0.1; // 90% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d2 = max(dot(delta, delta), 0.001);
+ float r2 = r1 * r1;
+
+ float atten = 1.0 - max(d2 - r2, 0.0) / max((rr - r2), 0.001);
+
+ w = 1.0 / d2;
+ w *= atten;
+ }
+
+ vi = v;
+
+ v -= c;
+ vec3 d = normalize(v);
+
+ v = env_mat * v;
+
+ vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod);
+
+ wi = d * ret.a * 256.0+c;
+
+ return ret.rgb;
+}
+
+// Tap an irradiance map
+// pos - position of pixel
+// dir - pixel normal
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i)
+{
+ // parallax adjustment
+ vec3 v;
+ if (refIndex[i].w < 0)
+ {
+ v = boxIntersect(pos, dir, i);
+ w = 1.0;
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+ float p = float(abs(refIndex[i].w)); // priority
+ float rr = r * r; // radius squred
+
+ v = sphereIntersect(pos, dir, c, rr);
+
+ float r1 = r * 0.1; // 75% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d2 = dot(delta, delta);
+ float r2 = r1 * r1;
+
+ w = 1.0 / d2;
+
+ float atten = 1.0 - max(d2 - r2, 0.0) / (rr - r2);
+ w *= atten;
+ }
+
+ v -= c;
+ v = env_mat * v;
+ {
+ return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;
+ }
+}
+
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
+{
+ float wsum = 0.0;
+ vec3 col = vec3(0,0,0);
+ float vd2 = dot(pos,pos); // view distance squared
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ if (abs(refIndex[i].w) < max_priority)
+ {
+ continue;
+ }
+
+ float w;
+ vec3 vi, wi;
+ vec3 refcol;
+
+
+ {
+ if (errorCorrect && refIndex[i].w >= 0)
+ { // error correction is on and this probe is a sphere
+ //take a sample to get depth value, then error correct
+ refcol = tapRefMap(pos, dir, w, vi, wi, abs(lod + 2), refSphere[i].xyz, i);
+
+ //adjust lookup by distance result
+ float d = length(vi - wi);
+ vi += dir * d;
+
+ vi -= refSphere[i].xyz;
+
+ vi = env_mat * vi;
+
+ refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
+
+ // weight by vector correctness
+ vec3 pi = normalize(wi - pos);
+ w *= max(dot(pi, dir), 0.1);
+ //w = pow(w, 32.0);
+ }
+ else
+ {
+ refcol = tapRefMap(pos, dir, w, vi, wi, lod, refSphere[i].xyz, i);
+ }
+
+ col += refcol.rgb*w;
+
+ wsum += w;
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+
+ return col;
+}
+
+vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
+{
+ // modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further
+ // as irradiance map mixing is tuned independently of radiance map mixing
+ float wsum = 0.0;
+ vec3 col = vec3(0,0,0);
+ float vd2 = dot(pos,pos); // view distance squared
+
+ float minweight = 1.0;
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ if (abs(refIndex[i].w) < max_priority)
+ {
+ continue;
+ }
+
+ {
+ float w;
+ vec3 refcol = tapIrradianceMap(pos, dir, w, refSphere[i].xyz, i);
+
+ col += refcol*w;
+
+ wsum += w;
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+
+ return col;
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+{
+ // TODO - don't hard code lods
+ float reflection_lods = 6;
+ preProbeSample(pos);
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm);
+
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness)
+{
+ sampleReflectionProbes(ambenv, glossenv,
+ pos, norm, glossiness, false);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity)
+{
+ // TODO - don't hard code lods
+ float reflection_lods = 7;
+ preProbeSample(pos);
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm);
+
+ if (glossiness > 0.0)
+ {
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false);
+ }
+
+ if (envIntensity > 0.0)
+ {
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
+ }
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+ glossenv *= 0.5; // fudge darker
+ float fresnel = clamp(1.0+dot(normalize(pos.xyz), norm.xyz), 0.3, 1.0);
+ fresnel *= fresnel;
+ fresnel *= spec.a;
+ glossenv *= spec.rgb*fresnel;
+ glossenv *= vec3(1.0) - color; // fake energy conservation
+ color.rgb += glossenv*0.5;
+}
+
+ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+ {
+ vec3 reflected_color = legacyenv;
+ vec3 lookAt = normalize(pos);
+ float fresnel = 1.0+dot(lookAt, norm.xyz);
+ fresnel *= fresnel;
+ fresnel = min(fresnel+envIntensity, 1.0);
+ reflected_color *= (envIntensity*fresnel);
+ color = mix(color.rgb, reflected_color*0.5, envIntensity);
+ }
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
deleted file mode 100644
index c8991f7a18..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3/deferred/shVisF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
- out vec4 frag_color;
-#else
- #define frag_color gl_FragColor
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// Fragment shader for L1 SH debug rendering
-/////////////////////////////////////////////////////////////////////////
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-uniform mat3 inv_modelviewprojection;
-
-VARYING vec4 vary_pos;
-
-void main(void)
-{
- vec2 coord = vary_pos.xy + vec2(0.5,0.5);
-
- coord.x *= (1.6/0.9);
-
- if (dot(coord, coord) > 0.25)
- {
- discard;
- }
-
- vec4 n = vec4(coord*2.0, 0.0, 1);
- //n.y = -n.y;
- n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0));
- //n.xyz = inv_modelviewprojection * n.xyz;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(
- dot(l1r, l1tap * n),
- dot(l1g, l1tap * n),
- dot(l1b, l1tap * n));
-
- //indirect = pow(indirect, vec3(0.45));
- indirect *= 3.0;
-
- frag_color = vec4(indirect, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
deleted file mode 100644
index 345c07a354..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file shadowAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 pos;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-
- frag_color = computeMoments(length(pos), float a);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
deleted file mode 100644
index af1461c297..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float target_pos_x;
-VARYING vec4 pos;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- pos_w = pos.w;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
deleted file mode 100644
index 50f1ffd626..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 getPosition(vec2 screen_coord);
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- vec4 pos = getPosition(vary_texcoord0.xy);
-
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < 0.88) // treat as semi-transparent
- {
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = computeMoments(length(pos.xyz), alpha);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
deleted file mode 100644
index 6a646f5e9e..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
deleted file mode 100644
index 3350267130..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file class3/deferred/shadowF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
deleted file mode 100644
index 2f69a353e8..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * @file class3/deferred/shadowUtil.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform sampler2D shadowMap0;
-uniform sampler2D shadowMap1;
-uniform sampler2D shadowMap2;
-uniform sampler2D shadowMap3;
-uniform sampler2D shadowMap4;
-uniform sampler2D shadowMap5;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform vec2 shadow_res;
-uniform vec2 proj_shadow_res;
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float shadow_bias;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-float getDepth(vec2 screenpos);
-vec3 getNorm(vec2 screenpos);
-vec4 getPosition(vec2 pos_screen);
-
-float ReduceLightBleeding(float p_max, float Amount)
-{
- return smoothstep(Amount, 1, p_max);
-}
-
-float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount)
-{
- float p = (t <= m.x) ? 1.0 : 0.0;
-
- float v = m.y - (m.x*m.x);
- v = max(v, min_v);
-
- float d = t - m.x;
-
- float p_max = v / (v + d*d);
-
- p_max = ReduceLightBleeding(p_max, Amount);
-
- return max(p, p_max);
-}
-
-vec4 computeMoments(float depth, float a)
-{
- float m1 = depth;
- float dx = dFdx(depth);
- float dy = dFdy(depth);
- float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy);
- return vec4(m1, m2, a, max(dx, dy));
-}
-
-float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9);
-}
-
-float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- lpos.xyz /= lpos.w;
- lpos.xy *= 0.5;
- lpos.xy += 0.5;
- return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9);
-}
-
-#if VSM_POINT_SHADOWS
-float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map)
-{
- vec4 moments = textureCube(shadow_cube_map, light_direction);
- return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25);
-}
-#endif
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- vec4 spos = vec4(pos,1.0);
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
-
- float shadow = 0.0f;
- float weight = 1.0;
-
- if (spos.z < near_split.z)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]);
- weight += 1.0f;
- }
- if (spos.z < near_split.y)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]);
- weight += 1.0f;
- }
- if (spos.z < near_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]);
- weight += 1.0f;
- }
- if (spos.z > far_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]);
- weight += 1.0f;
- }
-
- shadow /= weight;
-
- return shadow;
-}
-
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- pos += norm * spot_shadow_offset;
- return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
deleted file mode 100644
index 6577fe0ecf..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file class3/deferred/shadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * 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$
- */
-
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
deleted file mode 100644
index a0b082ed7c..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @file class3/deferred/skyF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D rainbow_map;
-uniform sampler2D halo_map;
-
-uniform float moisture_level;
-uniform float droplet_radius;
-uniform float ice_level;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 ColorFromRadiance(vec3 radiance);
-vec3 rainbow(float d)
-{
- // d is the dot product of view and sun directions, so ranging -1.0..1.0
- // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
- // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
-
- // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
- // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
- // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
- d = clamp(-0.575 - d, 0.0, 1.0);
-
- // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
- // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
- // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
- float interior_coord = max(0.0, d - 0.25) * 4.2857;
- d = clamp(d, 0.0, 0.25) + interior_coord;
-
- float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
-}
-
-vec3 halo22(float d)
-{
- float v = sqrt(max(0, 1 - (d*d)));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
-}
-
-void main()
-{
- vec3 pos = vec3((vary_frag * 2.0) - vec2(1.0, 1.0f), 1.0);
- vec4 view_pos = (inv_proj * vec4(pos, 1.0f));
-
- view_pos /= view_pos.w;
-
- vec3 view_ray = (inv_modelview * vec4(view_pos.xyz, 0.0f)).xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance);
- vec3 solar_luminance = GetSolarLuminance();
-
- // If the view ray intersects the Sun, add the Sun radiance.
- float s = dot(view_direction, sun_direction);
-
- // cheesy solar disc...
- if (s >= (sun_size * 0.999))
- {
- radiance_sun += pow(smoothstep(0.0, 1.3, (s - (sun_size * 0.9))), 2.0) * solar_luminance * transmittance;
- }
- s = smoothstep(0.9, 1.0, s) * 16.0f;
-
- vec3 color = ColorFromRadiance(radiance_sun);
-
- float optic_d = dot(view_direction, sun_direction);
- vec3 halo_22 = halo22(optic_d);
-
- color.rgb += rainbow(optic_d) * optic_d;
- color.rgb += halo_22;
-
- color = pow(color, vec3(1.0/2.2));
-
- frag_data[0] = vec4(color, 1.0 + s);
- frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 7ed9e7b4fc..879f4ef510 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -1,31 +1,35 @@
-/**
+/**
* @file class3/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
-
+
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
-/*[EXTRA_CODE_HERE]*/
+#define FLT_MAX 3.402823466e+38
+
+#define REFMAP_COUNT 256
+#define REF_SAMPLE_COUNT 64 //maximum number of samples to consider
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -36,142 +40,205 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D altDiffuseMap; // PBR: irradiance, skins/default/textures/default_irradiance.png
+
+const float M_PI = 3.14159265;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
uniform sampler2DRect lightMap;
+#endif
+
uniform sampler2DRect depthMap;
uniform sampler2D lightFunc;
-uniform samplerCube environmentMap;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform float cloud_shadow;
-uniform float max_y;
-uniform vec4 glow;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
uniform vec2 screen_res;
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten);
-vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance);
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+// reflection probe interface
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
-vec3 ColorFromRadiance(vec3 radiance);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
#endif
-void main()
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPositionWithDepth(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
+ vec2 tc = vary_fragcoord.xy;
+ float depth = texture2DRect(depthMap, tc.xy).r;
+ vec4 pos = getPositionWithDepth(tc, depth);
+ vec4 norm = texture2DRect(normalMap, tc);
float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
+ norm.xyz = getNorm(tc);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+ vec4 baseColor = texture2DRect(diffuseRect, tc);
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive
- vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
- diffuse.rgb = srgb_to_linear(diffuse.rgb);
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+#endif
+
+#if defined(HAS_SUN_SHADOW)
+ float scol = max(scol_ambocc.r, baseColor.a);
+#else
+ float scol = 1.0;
+#endif
+#if defined(HAS_SSAO)
+ float ambocc = scol_ambocc.g;
+#else
+ float ambocc = 1.0;
+#endif
- vec3 col;
+ vec3 color = vec3(0);
float bloom = 0.0;
- {
- vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
- float scol = max(scol_ambocc.r, diffuse.a);
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
- float ambocc = scol_ambocc.g;
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 orm = texture2DRect(specularRect, tc).rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ float ao = orm.r * ambocc;
+
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos.xyz, norm.xyz, gloss);
+
+ // Take maximium of legacy ambient vs irradiance sample as irradiance
+ // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here
+ irradiance = max(amblit,irradiance);
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
+ vec3 v = -normalize(pos.xyz);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+ }
+ else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ {
+ //should only be true of WL sky, just port over base color value
+ color = srgb_to_linear(baseColor.rgb);
+ }
+ else
+ {
+ // legacy shaders are still writng sRGB to gbuffer
+ baseColor.rgb = srgb_to_linear(baseColor.rgb);
+ spec.rgb = srgb_to_linear(spec.rgb);
- indirect = clamp(indirect, vec3(0), vec3(1.0));
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- vec3 transmittance;
- vec3 sky_irradiance;
- vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance);
- vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance);
+ vec3 irradiance = vec3(0);
+ vec3 glossenv = vec3(0);
+ vec3 legacyenv = vec3(0);
- vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
- vec3 atmo_color = ColorFromRadiance(radiance);
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+
+ // use sky settings ambient or irradiance map sample, whichever is brighter
+ irradiance = max(amblit, irradiance);
- col = atmo_color + indirect;
- col *= transmittance;
- col *= diffuse.rgb;
+ // apply lambertian IBL only (see pbrIbl)
+ color.rgb = irradiance * ambocc;
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 sun_contrib = min(da, scol) * sunlit;
+ color.rgb += sun_contrib;
+ color.rgb *= baseColor.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- if (spec.a > 0.0) // specular reflection
+ if (spec.a > 0.0) // specular reflection
{
- // the old infinite-sky shiny reflection
- //
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color;
-
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+
// add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
- bloom = dot(spec_contrib, spec_contrib);
- col += spec_contrib;
- }
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ color.rgb += spec_contrib;
- col = mix(col, diffuse.rgb, diffuse.a);
+ // add radiance map
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+ }
+ color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);
+
if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz;
- vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance);
- vec3 refcol = ColorFromRadiance(radiance_sun);
- col = mix(col.rgb, refcol, envIntensity);
+ { // add environment map
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
}
-
- /*if (norm.w < 0.5)
- {
- col = scaleSoftClipFrag(col);
- }*/
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
+
+ color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a);
+ color = scaleSoftClipFragLinear(color);
}
- //output linear since gamma correction happens down stream
- frag_color.rgb = col;
- frag_color.a = bloom;
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ #endif
+
+ frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index 56b0f4e5ce..3274153a46 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -1,9 +1,9 @@
/**
- * @file spotLightF.glsl
+ * @file class3\deferred\spotLightF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,6 +28,16 @@
/*[EXTRA_CODE_HERE]*/
+#define DEBUG_ANY_LIGHT_TYPE 0 // Output green light cone
+#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in green
+#define DEBUG_PBR_LIGHT_TYPE 0 // Show PBR objects in green
+#define DEBUG_PBR_SPOT 0
+#define DEBUG_PBR_SPOT_DIFFUSE 0
+#define DEBUG_PBR_SPOT_SPECULAR 0
+
+#define DEBUG_SPOT_NL 0 // monochome area effected by light
+#define DEBUG_SPOT_ZERO 0 // Output zero for spotlight
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -38,10 +48,11 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform sampler2DRect emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
+uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
@@ -71,217 +82,209 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
+vec2 getScreenXY(vec4 clip_point);
+vec3 srgb_to_linear(vec3 c);
+vec4 texture2DLodSpecular(vec2 tc, float lod);
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
+vec4 getPosition(vec2 pos_screen);
+const float M_PI = 3.14159265;
-vec4 getPosition(vec2 pos_screen);
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
-void main()
+void main()
{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ vec3 final_color = vec3(0,0,0);
+ vec2 tc = getScreenXY(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+
+ vec3 lv;
+ vec4 proj_tc;
+ float dist, l_dist;
+ if (clipProjectedLightVars(trans_center, pos, dist, l_dist, lv, proj_tc))
{
discard;
}
-
+
float shadow = 1.0;
-
+
if (proj_shadow_idx >= 0)
{
- vec4 shd = texture2DRect(lightMap, frag.xy);
+ vec4 shd = texture2DRect(lightMap, tc);
shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
shadow += shadow_fade;
shadow = clamp(shadow, 0.0, 1.0);
}
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5) + 1.0;
- float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
{
discard;
}
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
- vec3 dlit = vec3(0, 0, 0);
+ lv = proj_origin-pos.xyz; // NOTE: Re-using lv
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
+ vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
+ vec4 spec = texture2DRect(specularRect, tc);
+ vec3 dlit = vec3(0, 0, 0);
+ vec3 slit = vec3(0, 0, 0);
+
+ vec3 amb_rgb = vec3(0);
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- float amb_da = proj_ambiance;
- float lit = 0.0;
+ vec3 colorEmissive = texture2DRect(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- if (da > 0.0)
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
+ if (proj_tc.x > 0.0 && proj_tc.x < 1.0
+ && proj_tc.y > 0.0 && proj_tc.y < 1.0)
{
- lit = da * dist_atten * noise;
+ float lit = 0.0;
+ float amb_da = 0.0;
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
+ if (nl > 0.0)
+ {
+ amb_da += (nl*0.5 + 0.5) * proj_ambiance;
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
- if (spec.a > 0.0)
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
+
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
+ }
+ }
+ else
{
- dlit *= min(da*6.0, 1.0) * dist_atten;
- vec3 npos = -normalize(pos);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
{
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (nl > 0.0)
+ {
+ lit = nl * dist_atten * noise;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ final_color = dlit*lit*diffuse*shadow;
+
+ amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
+
+ vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ final_color += diffuse.rgb*amb_rgb;
+ #if DEBUG_LEG_LIGHT_TYPE
+ final_color = vec3(0,0.5,0);
+ #endif
}
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
+ if (spec.a > 0.0)
+ {
+ dlit *= min(nl*6.0, 1.0) * dist_atten;
+ float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ final_color += speccol;
+ }
+ }
+
+ if (envIntensity > 0.0)
{
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ vec3 ref = reflect(normalize(pos), n);
- if (stc.z > 0.0)
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
+
+ if (ds < 0.0)
{
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+
+ if (stc.z > 0.0)
{
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
}
}
}
}
-
+
+#if DEBUG_PBR_SPOT_DIFFUSE
+ final_color = vec3(nl * dist_atten);
+#endif
+#if DEBUG_SPOT_NL
+ final_color = vec3(nl);
+#endif
+#if DEBUG_SPOT_ZERO
+ final_color = vec3(0,0,0);
+#endif
+#if DEBUG_ANY_LIGHT_TYPE
+ final_color = vec3(0,0.3333,0);
+#endif
+
//not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
+ final_color = max(final_color, vec3(0.0));
- frag_color.rgb = col;
+ //output linear colors as gamma correction happens down stream
+ frag_color.rgb = final_color;
frag_color.a = 0.0;
+#endif // LOCAL_LIGHT_KILL
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
deleted file mode 100644
index 112b498c90..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class3\deferred\sunLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2, shadows, no SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.g = 1.0f;
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
deleted file mode 100644
index 342a2ff3ed..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class3\deferred\sunLightSSAOF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2 -- shadows and SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-uniform vec3 sun_dir;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.b = calcAmbientOcclusion(pos, norm, pos_screen);
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
deleted file mode 100644
index 41673d1669..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file treeShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float d, float a);
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
-
- if (alpha < minimum_alpha)
- {
- discard;
- }
-
- frag_color = computeMoments(length(pos), 1.0);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos.z/pos.w*0.5+0.5, 0.0);
-#endif
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
deleted file mode 100644
index 15e769ac10..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file treeShadowV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- //transform vertex
- pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
deleted file mode 100644
index 02000d90ca..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file waterV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-
-uniform vec2 d1;
-uniform vec2 d2;
-uniform float time;
-uniform vec3 eyeVec;
-uniform float waterHeight;
-
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-VARYING vec4 vary_position;
-
-float wave(vec2 v, float t, float f, vec2 d, float s)
-{
- return (dot(d, v)*f + t*s)*f;
-}
-
-void main()
-{
- //transform vertex
- vec4 pos = vec4(position.xyz, 1.0);
- mat4 modelViewProj = modelview_projection_matrix;
-
- vec4 oPosition;
-
- //get view vector
- vec3 oEyeVec;
- oEyeVec.xyz = pos.xyz-eyeVec;
-
- float d = length(oEyeVec.xy);
- float ld = min(d, 2560.0);
-
- pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
- view.xyz = oEyeVec;
-
- d = clamp(ld/1536.0-0.5, 0.0, 1.0);
- d *= d;
-
- oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
- vary_position = modelview_matrix * oPosition;
- oPosition = modelViewProj * oPosition;
-
- refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
-
- //get wave position parameter (create sweeping horizontal waves)
- vec3 v = pos.xyz;
- v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
-
- //push position for further horizon effect.
- pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
- pos.w = 1.0;
- pos = modelview_matrix*pos;
-
- //pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
- //get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
- view.w = bigWave.y;
- refCoord.w = bigWave.x;
-
- gl_Position = oPosition;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 540226e672..a5e0adf8fa 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file underWaterF.glsl
+ * @file class3\environment\underWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,19 +23,15 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_color;
uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
+uniform sampler2D bumpMap;
+
+#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D refTex;
uniform sampler2D screenDepth;
+#endif
uniform vec4 fogCol;
uniform vec3 lightDir;
@@ -49,7 +45,7 @@ uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
-uniform float waterFogDensity;
+uniform vec3 waterFogColorLinear;
uniform float waterFogKS;
uniform vec2 screenRes;
@@ -57,47 +53,15 @@ uniform vec2 screenRes;
VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+in vec3 vary_position;
-vec2 encode_normal(vec3 n);
-
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
- //normalize view vector
- vec3 view = normalize(viewVec);
- float es = -view.z;
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- //get object depth
- float depth = length(viewVec);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
- return color * D + kc * L;
-}
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
void main()
{
vec4 color;
-
- //get detail normals
+
+ //get detail normals
vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
@@ -106,10 +70,12 @@ void main()
//figure out distortion vector (ripply)
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
distort = distort+wavef.xy*refScale;
-
- vec4 fb = texture2D(screenTex, distort);
- frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
- frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture2D(screenTex, distort);
+#else
+ vec4 fb = vec4(waterFogColorLinear, 0.0);
+#endif
+
+ frag_color = applyWaterFogViewLinear(vary_position, fb);
}
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
new file mode 100644
index 0000000000..a6517be433
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -0,0 +1,265 @@
+/**
+ * @file waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// class3/environment/waterF.glsl
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
+// PBR interface
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+#ifdef TRANSPARENT_WATER
+uniform sampler2D screenTex;
+uniform sampler2D screenDepth;
+#endif
+
+uniform sampler2D refTex;
+
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
+
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+in vec3 vary_light_dir;
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+vec3 srgb_to_linear(vec3 col);
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 vN, vT, vB;
+
+vec3 transform_normal(vec3 vNt)
+{
+ return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
+
+vec3 getPositionWithNDC(vec3 ndc);
+
+void main()
+{
+ vec4 color;
+
+ vN = vary_normal;
+ vT = vary_tangent;
+ vB = cross(vN, vT);
+
+ vec3 pos = vary_position.xyz;
+
+ float dist = length(pos.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(pos.xyz);
+
+ //get wave normals
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture(bumpMap, bigwave, -2 ).xyz*2.0-1.0;
+ vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ wave1 = transform_normal(wave1);
+ wave2 = transform_normal(wave2);
+ wave3 = transform_normal(wave3);
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+
+ //wavef.z *= max(-viewVec.z, 0.1);
+
+ wavef = normalize(wavef);
+
+ //get base fresnel components
+
+ vec3 df = vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset;
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ vec2 dmod_scale = vec2(dmod*dmod, dmod);
+
+ float df1 = df.x + df.y + df.z;
+
+ //wavef = normalize(wavef - vary_normal);
+ //wavef = vary_normal;
+
+ vec3 waver = reflect(viewVec, -wavef)*3;
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
+ distort2 = clamp(distort2, vec2(0), vec2(0.99));
+
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture2D(screenTex, distort2);
+ float depth = texture2D(screenDepth, distort2).r;
+ vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
+
+ if (refPos.z > pos.z-0.05)
+ {
+ //we sampled an above water sample, don't distort
+ distort2 = distort;
+ fb = texture2D(screenTex, distort2);
+ depth = texture2D(screenDepth, distort2).r;
+ refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
+ }
+
+ fb = applyWaterFogViewLinear(refPos, fb);
+#else
+ vec4 fb = vec4(waterFogColorLinear.rgb, 0.0);
+#endif
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+ sunlit = vec3(1); // TODO -- figure out why sunlit is breaking at some view angles
+ vec3 v = -viewVec;
+ float NdotV = clamp(abs(dot(wavef.xyz, v)), 0.001, 1.0);
+
+ float metallic = fresnelOffset * 0.1; // fudge -- use fresnelOffset as metalness
+ float roughness = 0.1;
+ float gloss = 1.0 - roughness;
+
+ vec3 baseColor = vec3(0.25);
+ vec3 f0 = vec3(0.04);
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
+ diffuseColor *= gloss;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 refnorm = normalize(wavef + vary_normal);
+ //vec3 refnorm = wavef;
+
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss, true);
+ radiance *= 0.5;
+ irradiance = fb.rgb;
+
+ color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
+
+ // fudge -- for punctual lighting, pretend water is metallic
+ diffuseColor = vec3(0);
+ specularColor = vec3(1);
+ roughness = 0.1;
+ float scol = 1.0; // TODO -- incorporate shadow map
+
+ //color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
+
+ //get specular component
+ float spec = clamp(dot(vary_light_dir, (reflect(viewVec, wavef))), 0.0, 1.0);
+
+ //harden specular
+ spec = pow(spec, 128.0);
+
+ color.rgb += spec * specular;
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+ color.rgb = scaleSoftClipFragLinear(color.rgb);
+
+ color.a = 0.f;
+ //color.rgb = fb.rgb;
+ //color.rgb = vec3(depth*depth*depth*depth);
+ //color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
+ //color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
+ //color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
+
+ //color.rgb = radiance;
+ frag_color = color;
+
+#if defined(WATER_EDGE)
+ gl_FragDepth = 0.9999847f;
+#endif
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
deleted file mode 100644
index c6ea3ec9d4..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-in vec3 view_dir;
-
-uniform vec3 cameraPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance);
-
-void main()
-{
- vec3 view_direction = normalize(view_dir);
-
- vec3 camPos = cameraPosLocal;
- vec3 transmittance;
- vec3 sky_illum;
- vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_dir, transmittance);
- vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_dir, sky_illum);
-
- //radiance *= transmittance;
-
- // If the view ray intersects the Sun, add the Sun radiance.
- if (dot(view_direction, sun_dir) >= sun_size)
- {
- radiance = radiance + transmittance * GetSolarLuminance();
- }
-
- //vec3 color = vec3(1.0) - exp(-radiance);
- //color = pow(color, vec3(1.0 / 2.2));
-
- frag_color.rgb = radiance;
-
- frag_color.a = 1.0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
deleted file mode 100644
index 65bb00b1f6..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-// Inputs
-uniform vec3 camPosLocal;
-
-out vec3 view_dir;
-
-void main()
-{
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // this will be normalized in the frag shader...
- view_dir = position.xyz - camPosLocal.xyz;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
deleted file mode 100644
index 2b70ba76dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file class3\wl\atmosphericsF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-vec3 scaleSoftClipFrag(vec3 light);
-
-uniform int no_atmo;
-
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- light *= atten.r;
- light += additive;
- return light * 2.0;
-}
-
-vec3 atmosLighting(vec3 light)
-{
- return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
deleted file mode 100644
index b76192d73f..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file class3\wl\atmosphericsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-// VARYING param funcs
-void setSunlitColor(vec3 v);
-void setAmblitColor(vec3 v);
-void setAdditiveColor(vec3 v);
-void setAtmosAttenuation(vec3 v);
-void setPositionEye(vec3 v);
-
-vec3 getAdditiveColor();
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-void calcAtmospherics(vec3 inPositionEye) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
- vec3 tmpsunlit = vec3(1);
- vec3 tmpamblit = vec3(1);
- vec3 tmpaddlit = vec3(1);
- vec3 tmpattenlit = vec3(1);
- calcAtmosphericVars(inPositionEye, vec3(0), 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, true);
- setSunlitColor(tmpsunlit);
- setAmblitColor(tmpamblit);
- setAdditiveColor(tmpaddlit);
- setAtmosAttenuation(tmpattenlit);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
deleted file mode 100644
index 545a32a227..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file class3\wl\transportF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-
-uniform int no_atmo;
-
-vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- // fullbright responds minimally to atmos scatter effects
- light *= min(15.0 * atten.r, 1.0);
- light += (0.1 * additive);
- return light * 2.0;
-}
-
-vec3 atmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return vec3(1,0,1);
- //return atmosTransportFrag(light * 0.5, additive * (brightness * 0.5 + 0.5), atten);
-}
-
-vec3 fullbrightAtmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightShinyAtmosTransport(vec3 light)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/shader_hierarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt
index 8ef04d8e1f..81e1327178 100644
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt
@@ -1,177 +1,15 @@
-Class 3 is highest quality / lowest performance
-Class 2 is medium quality / medium performance
-Class 1 is lowest quality / highest performance
+Second Life shader variants are referred to as "classes."
-Shaders WILL fall back to "lower" classes for functionality.
+When a shader of a particular class is loaded, a lower class may
+be loaded if the class requested doesn't exist or fails to load
+for any reason. In general, shaders that require more resources
+or later hardware capabilities should be higher class and
+lower classes can be used for fallback implementations or lower
+detail settings.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
- main() - avatar/avatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarF.glsl - gAvatarProgram
- main() - avatar/avatarF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballV.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLightingSpecular() - lighting/lightSpecularV.glsl
- sumLightsSpecular() - lighting/sumLightsSpecularV.glsl
- calcDirectionalLightSpecular() - lighting/lightFuncSpecularV.glsl
- calcPointLightSpecular() - lighting/lightFuncSpecularV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
- atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballF.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarV.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarF.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram
- texgen_object() - environment/terrainV.glsl
- main() - environment/terrainV.glsl
- texgen_object() - environment/terrainV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainF.glsl - gTerrainProgram
- main() - environment/terrainF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainWaterF.glsl - gTerrainWaterProgram
- main() - environment/terrainWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/underWaterF.glsl - gUnderWaterProgram
- applyWaterFog() - environment/underWaterF.glsl (NOTE: different than one in waterFogF.glsl)
- main() - environment/underWaterF.glsl
- applyWaterFog() - environment/underWaterF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterV.glsl - gWaterProgram, gUnderWaterProgram
- main() - environment/waterV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterF.glsl - gWaterProgram
- main() - environment/waterF.glsl
- atmosTransport() - windlight/transportF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightV.glsl - gObjectFullbrightProgram, gObjectFullbrightWaterProgram
- main() - objects/fullbrightV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightF.glsl - gObjectFullbrightProgram
- main() - objects/fullbrightF.glsl
- fullbright_lighting() - lighting/lightFullbrightF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyV.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyF.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyF.glsl
- fullbright_shiny_lighting() - lighting/lightFullbrightShinyF.glsl
- fullbrightShinyAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightWaterF.glsl - gObjectFullbrightWaterProgram
- main() - objects/fullbrightWaterF.glsl
- fullbright_lighting_water() - lighting/lightFullbrightWaterF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram
- main() - objects/shinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- calcLighting(vec4) - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyF.glsl - gObjectShinyProgram
- main() - objects/shinyF.glsl
- shiny_lighting() - lighting/lightShinyF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyWaterF.glsl - gObjectShinyWaterProgram
- main() - objects/shinyWaterF.glsl
- shiny_lighting_water() - lighting/lightShinyWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram
- main() - objects/simpleV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleF.glsl - gObjectSimpleProgram
- main() - objects/simpleF.glsl
- default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleWaterF.glsl - gObjectSimpleWaterProgram, gAvatarWaterProgram
- main() - objects/simpleWaterF.glsl
- default_lighting_water() - lighting/lightWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyV.glsl - gWLSkyProgram
- main() - windlight/skyV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyF.glsl - gWLSkyProgram
- main() - windlight/skyF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsV.glsl - gWLCloudProgram
- main() - windlight/cloudsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsF.glsl - gWLCloudProgram
- main() - windlight/cloudsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
+Which class is chosen will generally depend on graphics preferences.
+
+Previously, someone tried to enumerate the shaders here, but don't do
+that. It messes with searches and the shader hierarchy changes often.
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
deleted file mode 100644
index 8462df207b..0000000000
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="TRUE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="1.0"/>
- <!--Short Range-->
- <RenderFarClip value="256"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="4"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="1.0"/>
- <!--Avater Impostors and Visual Muting Limits (real defaults set
- based on default graphics setting -->
- <RenderAvatarMaxNonImpostors value="0"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1500.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="2.0"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="TRUE"/>
- <!--SSAO Enabled-->
- <RenderDeferredSSAO value="TRUE"/>
- <!--Full Shadows-->
- <RenderShadowDetail value="2"/>
-</settings>
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 2241a12545..6cfc0b0be2 100644
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
@@ -2,15 +2,15 @@
<bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/>
- <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
- <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>
<collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/>
@@ -23,58 +23,58 @@
<bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
- <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -86,29 +86,29 @@
<collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -123,49 +123,49 @@
<collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -200,30 +200,30 @@
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae
new file mode 100644
index 0000000000..085b2c7309
--- /dev/null
+++ b/indra/newview/cube.dae
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
+ </contributor>
+ <created>2018-10-25T16:29:03Z</created>
+ <modified>2022-02-18T00:00:00Z</modified>
+ <unit meter="1.000000"/>
+ <up_axis>Y_UP</up_axis>
+ </asset>
+
+ <library_materials>
+ <material id="Blue" name="Blue">
+ <instance_effect url="#effect_Blue"/>
+ </material>
+ </library_materials>
+
+
+ <library_effects>
+ <effect id="effect_Blue">
+ <profile_COMMON>
+ <technique sid="common">
+ <phong>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <color>0.137255 0.403922 0.870588 1</color>
+ </diffuse>
+ <specular>
+ <color>0.5 0.5 0.5 1</color>
+ </specular>
+ <shininess>
+ <float>16</float>
+ </shininess>
+ <transparent opaque="A_ONE">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ <index_of_refraction>
+ <float>1</float>
+ </index_of_refraction>
+ </phong>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+
+
+ <library_geometries>
+ <geometry id="F1" name="default_physics_shape">
+ <mesh>
+
+ <source id="cube-vertex-positions">
+ <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array>
+ <technique_common>
+ <accessor source="#ID2-array" count="24" stride="3">
+ <param name="X" type="float"/>
+ <param name="Y" type="float"/>
+ <param name="Z" type="float"/>
+ </accessor>
+ </technique_common>
+ </source>
+
+ <vertices id="cube-vertices">
+ <input semantic="POSITION" source="#cube-vertex-positions"/>
+ </vertices>
+
+ <triangles count="12" material="geometryElement5">
+ <input semantic="VERTEX" offset="0" source="#cube-vertices"/>
+ <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p>
+ </triangles>
+
+ </mesh>
+ </geometry>
+ </library_geometries>
+ <library_visual_scenes>
+
+
+ <visual_scene id="reportScene">
+ <!-- No Spaces allowed in Name -->
+ <node id="F1" name="Face1">
+ <instance_geometry url="#F1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="geometryElement5" target="#Blue"/>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+
+
+ <scene>
+ <instance_visual_scene url="#reportScene"/>
+ </scene>
+
+
+</COLLADA>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e04e38b9de..efd498183d 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 34
+version 40
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,7 +28,7 @@ version 34
//
list all
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -46,22 +46,24 @@ RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 4
+RenderTransparentWater 1 1
+RenderReflectionProbeDetail 1 2
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
-UseOcclusion 1 1
+UseOcclusion 1 0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
+RenderPBR 1 1
+RenderReflectionProbeCount 1 256
RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
@@ -78,7 +80,6 @@ RenderGLMultiThreaded 1 1
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -88,15 +89,12 @@ RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
RenderLocalLights 1 0
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionProbeDetail 1 -1
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
@@ -108,7 +106,6 @@ RenderFSAASamples 1 0
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -116,16 +113,13 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionProbeDetail 1 -1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
@@ -137,7 +131,6 @@ RenderFSAASamples 1 0
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -145,28 +138,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// Medium High Graphics Settings (deferred enabled)
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -174,28 +163,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Graphics Settings (deferred + SSAO)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -203,28 +188,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Ultra Graphics Settings (deferred + SSAO + shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -232,28 +213,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
@@ -261,8 +238,6 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderLocalLights 1 1
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -270,18 +245,17 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -296,29 +270,26 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
+RenderTransparentWater 1 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderReflectionProbeDetail 0 -1
list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
RenderGLMultiThreaded 1 0
-RenderGLContextCoreProfile 1 0
+RenderGLContextCoreProfile 1 0
-// AMD cards generally perform better when not using VBOs for streaming data
-// AMD cards also prefer an OpenGL Compatibility Profile Context
+// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 32
list AMD
-RenderUseStreamVBO 1 0
-RenderGLContextCoreProfile 1 0
-
+RenderReflectionProbeCount 1 32
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionProbeDetail 0 -1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index d319d26e1f..d40e7aff0b 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 38
+version 41
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,7 +28,7 @@ version 38
//
list all
RenderAnisotropic 1 0
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
@@ -46,7 +46,6 @@ RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -55,7 +54,7 @@ RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
-UseOcclusion 1 1
+UseOcclusion 1 0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -63,21 +62,22 @@ Disregard96DefaultDrawDistance 1 1
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
+RenderPBR 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
-RenderGLContextCoreProfile 1 0
+RenderGLContextCoreProfile 1 1
RenderGLMultiThreaded 1 0
+RenderReflectionProbeDetail 1 2
//
// Low Graphics Settings
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -87,27 +87,23 @@ RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
RenderLocalLights 1 0
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
+RenderReflectionProbeDetail 1 -1
//
// Medium Low Graphics Settings
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -115,28 +111,24 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
+RenderReflectionProbeDetail 1 -1
//
// Medium Graphics Settings (standard)
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -144,28 +136,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// Medium High Graphics Settings (deferred enabled)
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -173,28 +161,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 0
//
// High Graphics Settings (deferred + SSAO)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -202,28 +186,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// High Ultra Graphics Settings (deferred + SSAO + shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -231,28 +211,24 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
RenderLocalLights 1 1
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderUseAdvancedAtmospherics 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
@@ -260,8 +236,6 @@ RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderLocalLights 1 1
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -269,18 +243,17 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionProbeDetail 1 1
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -296,16 +269,11 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
@@ -321,6 +289,6 @@ RenderAnisotropic 1 0
RenderLocalLights 1 0
RenderFSAASamples 1 0
-list OSX_10_6_8
-RenderDeferred 0 0
-
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionProbeDetail 0 -1
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 7513908cb4..60e26274cb 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -351,11 +351,29 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
ClearErrors
+INSTALL_FILES_START:
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
%%INSTALL_FILES%%
+IfErrors 0 INSTALL_FILES_DONE
+ StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START
+ # MB_ABORTRETRYIGNORE does not accept IDIGNORE
+ Goto INSTALL_FILES_DONE
+
+INSTALL_FILES_CANCEL:
+ # We are quiting, cleanup.
+ # Silence warnings from RemoveProgFilesOnInst.
+ StrCpy $SKIP_DIALOGS "true"
+ Call RemoveProgFilesOnInst
+ MessageBox MB_OK $(ErrorSecondLifeInstallSupport)
+ Quit
+
+INSTALL_FILES_DONE:
+
# Pass the installer's language to the client to use as a default
StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
@@ -622,7 +640,9 @@ Function RemoveProgFilesOnInst
Push $0
StrCpy $0 0
-PREINSTALLREMOVE:
+ClearErrors
+
+PREINSTALL_REMOVE:
# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
Delete "$INSTDIR\$INSTEXE"
@@ -642,17 +662,17 @@ RMDir /r "$INSTDIR\llplugin"
IntOp $0 $0 + 1
-IfErrors 0 PREINSTALLDONE
- IntCmp $0 1 PREINSTALLREMOVE #try again once
- StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE
- MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE
+IfErrors 0 PREINSTALL_DONE
+ IntCmp $0 1 PREINSTALL_REMOVE #try again once
+ StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE
# MB_ABORTRETRYIGNORE does not accept IDIGNORE
- Goto PREINSTALLDONE
+ Goto PREINSTALL_DONE
-PREINSTALLFAIL:
+PREINSTALL_FAIL:
Quit
-PREINSTALLDONE:
+PREINSTALL_DONE:
# We are no longer including release notes with the viewer, so remove them.
Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 648ddbfb85..73f23086be 100644
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 188c30197a..7cc70e4c76 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
@@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer
; CheckNetworkConnection
LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..."
+; error during installation
+LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert."
+LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com."
+
; ask to remove user's data files
LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren."
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 0639d51e10..2eaf97d023 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index ee30651a38..364cc9f67e 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 7cd90ec314..2f34c0c87a 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 194062da9a..51214d3a9c 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index a54005ba14..296703d1a3 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 355d806866..299645bbb7 100644
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 97f5d2b44a..542c8654b5 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 65a9f4846d..4e53a4957d 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index e71886cc66..bae5029ad1 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index f5f0c6cbdf..7922d9df52 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index fba6a55da3..29b5a919bd 100644
--- a/indra/newview/licenses-mac.txt
+++ b/indra/newview/licenses-mac.txt
@@ -719,3 +719,55 @@ 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.
+
+
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 837d92139d..eddc9a4475 100644
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
@@ -796,3 +796,52 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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.
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b79af04c36..5250369813 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -96,6 +96,7 @@
#include "stringize.h"
#include "boost/foreach.hpp"
#include "llcorehttputil.h"
+#include "lluiusage.h"
using namespace LLAvatarAppearanceDefines;
@@ -574,6 +575,8 @@ void LLAgent::ageChat()
//-----------------------------------------------------------------------------
void LLAgent::moveAt(S32 direction, bool reset)
{
+ LLUIUsage::instance().logCommand("Agent.MoveAt");
+
mMoveTimer.reset();
LLFirstUse::notMoving(false);
@@ -713,6 +716,15 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
setControlFlags(AGENT_CONTROL_YAW_NEG);
}
+ U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
+ if ((getControlFlags() & mask) == mask)
+ {
+ // Rotation into both directions should cancel out
+ // But keep sending controls to simulator,
+ // it's needed for script based controls
+ gAgentCamera.setYawKey(0);
+ }
+
if (reset_view)
{
gAgentCamera.resetView();
@@ -2005,6 +2017,27 @@ void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32
//
gAgentCamera.updateLookAt(mouse_x, mouse_y);
+
+ // When agent has no parents, position updates come from setPositionAgent()
+ // But when agent has a parent (ex: is seated), position remains unchanged
+ // relative to parent and no parent's position update trigger
+ // setPositionAgent().
+ // But EEP's sky track selection still needs an update if agent has a parent
+ // and parent moves (ex: vehicles).
+ if (isAgentAvatarValid()
+ && gAgentAvatarp->getParent()
+ && !mOnPositionChanged.empty()
+ )
+ {
+ LLVector3d new_position = getPositionGlobal();
+ if ((mLastTestGlobal - new_position).lengthSquared() > 1.0)
+ {
+ // If the position has changed by more than 1 meter since the last time we triggered.
+ // filters out some noise.
+ mLastTestGlobal = new_position;
+ mOnPositionChanged(mFrameAgent.getOrigin(), new_position);
+ }
+ }
}
// friends and operators
@@ -3996,6 +4029,7 @@ void LLAgent::startTeleportRequest()
}
if (hasPendingTeleportRequest())
{
+ LLUIUsage::instance().logCommand("Agent.StartTeleportRequest");
mTeleportCanceled.reset();
if (!isMaturityPreferenceSyncedWithServer())
{
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 84a41113be..57a59d81c4 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -401,10 +401,9 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
LLQuaternion obj_rot = object->getRenderRotation();
LLVector3 obj_pos = object->getRenderPosition();
- BOOL is_avatar = object->isAvatar();
// if is avatar - don't do any funk heuristics to position the focal point
// see DEV-30589
- if (is_avatar)
+ if (object->isAvatar() || (object->isAnimatedObject() && object->getControlAvatar()))
{
return original_focus_point - obj_pos;
}
@@ -529,7 +528,6 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi
// or keep the focus point in the object middle when (relatively) far
// NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
// is almost always "tumble about middle" and not "spin around surface point"
- if (!is_avatar)
{
LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
@@ -1188,12 +1186,18 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera");
+extern BOOL gCubeSnapshot;
+
//-----------------------------------------------------------------------------
// updateCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::updateCamera()
{
LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
// - changed camera_skyward to the new global "mCameraUpVector"
mCameraUpVector = LLVector3::z_axis;
@@ -1417,7 +1421,7 @@ void LLAgentCamera::updateCamera()
F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
- if (!mFocusObject) // we differentiate on avatar mode
+ if (mFocusOnAvatar && !mFocusObject) // we differentiate on avatar mode
{
// for avatar-relative focus, we smooth in avatar space -
// the avatar moves too jerkily w/r/t global space to smooth there.
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index f981e08ff7..21df036cb7 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
-private:
-
void onServerRespond(LLAvatarPicks* picks);
+private:
+
/**
* Sets number of Picks.
*/
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index be168ff5dd..2e769dc737 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -37,6 +37,7 @@
#include "llgesturemgr.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllocaltextureobject.h"
@@ -1582,6 +1583,14 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ if (!item->isFinished())
+ {
+ LL_WARNS() << "Tried to edit wearable that isn't loaded" << LL_ENDL;
+ // Restart fetch or put item to the front
+ LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false);
+ return;
+ }
+
LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
{
@@ -1595,6 +1604,18 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
+ S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+ S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+ S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+ S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+ if (!shape_count || !hair_count || !eye_count || !skin_count)
+ {
+ // Don't let user edit wearables if avatar is cloud due to missing parts.
+ // Let user edit wearables if avatar is cloud due to missing textures.
+ LL_WARNS() << "Cannot modify wearable. Avatar is cloud and missing parts." << LL_ENDL;
+ return;
+ }
+
const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType());
LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance");
LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 39c9fa1bca..909f32cd21 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -60,6 +60,7 @@
#include "llappviewer.h"
#include "llcoros.h"
#include "lleventcoro.h"
+#include "lluiusage.h"
#include "llavatarpropertiesprocessor.h"
@@ -1426,6 +1427,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
bool replace,
LLPointer<LLInventoryCallback> cb)
{
+ LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearItem");
+
bool first = true;
LLInventoryObject::const_object_list_t items_to_link;
@@ -2761,6 +2765,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
<< "'" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearCategory");
if (gAgentCamera.cameraCustomizeAvatar())
{
@@ -3968,6 +3973,8 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
{
if (!isAgentAvatarValid()) return;
+ LLUIUsage::instance().logCommand("Avatar.CreateNewOutfit");
+
LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL;
gAgentWearables.notifyLoadingStarted();
@@ -4006,6 +4013,9 @@ void LLAppearanceMgr::wearBaseOutfit()
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
+ LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.RemoveItem");
+
if (ids_to_remove.empty())
{
LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
@@ -4485,6 +4495,8 @@ public:
"Quick Appearance");
if ( gInventory.getCategory( folder_uuid ) != NULL )
{
+ // Assume this is coming from the predefined avatars web floater
+ LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 55c0b31bf6..66316a18d4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -338,9 +338,6 @@ LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
bool gUseWireframe = FALSE;
-//use for remember deferred mode in wireframe switch
-bool gInitialDeferredModeForWireframe = FALSE;
-
LLMemoryInfo gSysMemory;
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
@@ -531,7 +528,7 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
- LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
+ LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
@@ -556,7 +553,7 @@ static void settings_to_globals()
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+ LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
@@ -566,12 +563,12 @@ static void settings_to_globals()
static void settings_modify()
{
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
- LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderBump = TRUE; // FALSE is deprecated -- gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated -- LLPipeline::sRenderBump&& gSavedSettings.getBOOL("RenderDeferred");
LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4]
- gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
+ gDebugGL = gDebugGLSession || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
@@ -1124,7 +1121,8 @@ bool LLAppViewer::init()
gGLActive = FALSE;
#if LL_RELEASE_FOR_DOWNLOAD
- if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
+ // Skip updater if this is a non-interactive instance
+ if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive)
{
LLProcess::Params updater;
updater.desc = "updater process";
@@ -1448,6 +1446,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@@ -1505,22 +1505,23 @@ bool LLAppViewer::doFrame()
// Render scene.
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
- if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" )
- pingMainloopTimeout("Main:Display");
- gGLActive = TRUE;
+ if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display");
+ pingMainloopTimeout("Main:Display");
+ gGLActive = TRUE;
- display();
+ display();
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
- pingMainloopTimeout("Main:Snapshot");
- LLFloaterSnapshot::update(); // take snapshots
- LLFloaterOutfitSnapshot::update();
- gGLActive = FALSE;
- }
- }
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot");
+ pingMainloopTimeout("Main:Snapshot");
+ gPipeline.mReflectionMapManager.update();
+ LLFloaterSnapshot::update(); // take snapshots
+ LLFloaterOutfitSnapshot::update();
+ gGLActive = FALSE;
+ }
+ }
}
{
@@ -2052,7 +2053,6 @@ bool LLAppViewer::cleanup()
}
sTextureFetch->shutDownTextureCacheThread() ;
- sTextureFetch->shutDownImageDecodeThread() ;
LLLFSThread::sLocal->shutdown();
LL_INFOS() << "Shutting down message system" << LL_ENDL;
@@ -2067,8 +2067,13 @@ bool LLAppViewer::cleanup()
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
delete sTextureCache;
sTextureCache = NULL;
- delete sTextureFetch;
- sTextureFetch = NULL;
+ if (sTextureFetch)
+ {
+ sTextureFetch->shutdown();
+ sTextureFetch->waitOnPending();
+ delete sTextureFetch;
+ sTextureFetch = NULL;
+ }
delete sImageDecodeThread;
sImageDecodeThread = NULL;
delete mFastTimerLogThread;
@@ -2182,11 +2187,23 @@ bool LLAppViewer::initThreads()
LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
+ //auto configure thread count
+ LLSD threadCounts = gSavedSettings.getLLSD("ThreadPoolSizes");
+
+ // get the number of concurrent threads that can run
+ S32 cores = std::thread::hardware_concurrency();
+
+ // The only configurable thread count right now is ImageDecode
+ // The viewer typically starts around 8 threads not including image decode,
+ // so try to leave at least one core free
+ S32 image_decode_count = llclamp(cores - 9, 1, 8);
+ threadCounts["ImageDecode"] = image_decode_count;
+ gSavedSettings.setLLSD("ThreadPoolSizes", threadCounts);
+
// Image decoding
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
- sImageDecodeThread,
enable_threads && true,
app_metrics_qa_mode);
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
@@ -2469,10 +2486,24 @@ bool LLAppViewer::initConfiguration()
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
+ BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
{
- LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ if (gDirUtilp->fileExists(settings_file_list))
+ {
+ LL_ERRS() << "Cannot load default configuration file settings_files.xml. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_ERRS() << "Default configuration file settings_files.xml not found. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
}
mSettingsLocationList = new SettingsFiles();
@@ -2695,19 +2726,14 @@ bool LLAppViewer::initConfiguration()
if (clp.hasOption("graphicslevel"))
{
- // User explicitly requested --graphicslevel on the command line. We
- // expect this switch has already set RenderQualityPerformance. Check
- // that value for validity.
- U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
- if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
- {
- // graphicslevel is valid: save it and engage it later. Capture
- // the requested value separately from the settings variable
- // because, if this is the first run, LLViewerWindow's constructor
- // will call LLFeatureManager::applyRecommendedSettings(), which
- // overwrites this settings variable!
- mForceGraphicsLevel = graphicslevel;
- }
+ // User explicitly requested --graphicslevel on the command line. We
+ // expect this switch has already set RenderQualityPerformance. Check
+ // that value for validity later.
+ // Capture the requested value separately from the settings variable
+ // because, if this is the first run, LLViewerWindow's constructor
+ // will call LLFeatureManager::applyRecommendedSettings(), which
+ // overwrites this settings variable!
+ mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance");
}
LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
@@ -2721,6 +2747,15 @@ bool LLAppViewer::initConfiguration()
ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
}
+ if (gSavedSettings.getBOOL("RenderDebugGLSession"))
+ {
+ gDebugGLSession = TRUE;
+ gDebugGL = TRUE;
+ // gDebugGL can cause excessive logging
+ // so it's limited to a single session
+ gSavedSettings.setBOOL("RenderDebugGLSession", FALSE);
+ }
+
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
@@ -3056,7 +3091,7 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
- if (mForceGraphicsLevel)
+ if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel)))
{
LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
@@ -3117,6 +3152,11 @@ bool LLAppViewer::isUpdaterMissing()
return mUpdaterNotFound;
}
+bool LLAppViewer::waitForUpdater()
+{
+ return !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !mUpdaterNotFound && !gNonInteractive;
+}
+
void LLAppViewer::writeDebugInfo(bool isStatic)
{
#if LL_WINDOWS && LL_BUGSPLAT
@@ -3197,7 +3237,28 @@ LLSD LLAppViewer::getViewerInfo() const
info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
#if LL_WINDOWS
- std::string drvinfo = gDXHardware.getDriverVersionWMI();
+ std::string drvinfo;
+
+ if (gGLManager.mIsIntel)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_INTEL);
+ }
+ else if (gGLManager.mIsNVIDIA)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_NVIDIA);
+ }
+ else if (gGLManager.mIsAMD)
+ {
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_AMD);
+ }
+
+ if (drvinfo.empty())
+ {
+ // Generic/substitute windows driver? Unknown vendor?
+ LL_WARNS("DriverVersion") << "Vendor based driver search failed, searching for any driver" << LL_ENDL;
+ drvinfo = gDXHardware.getDriverVersionWMI(LLDXHardware::GPU_ANY);
+ }
+
if (!drvinfo.empty())
{
info["GRAPHICS_DRIVER_VERSION"] = drvinfo;
@@ -3240,9 +3301,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
+ if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
+ version.serverVersion.begin()))
+ { // Normal case: Show type and build version.
+ version_string << version.serverType << " " << build_version << std::endl;
+ }
+ else
+ { // Mismatch: Show both versions.
+ version_string << version.serverVersion << "/" << build_version << std::endl;
+ }
info["VOICE_VERSION"] = version_string.str();
}
else
@@ -3435,7 +3505,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
+ gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
@@ -4206,6 +4276,15 @@ U32 LLAppViewer::getTextureCacheVersion()
}
//static
+U32 LLAppViewer::getDiskCacheVersion()
+{
+ // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
+ const U32 DISK_CACHE_VERSION = 1;
+
+ return DISK_CACHE_VERSION ;
+}
+
+//static
U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
@@ -4225,21 +4304,30 @@ bool LLAppViewer::initCache()
// initialize the new disk cache using saved settings
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
+ const U32 MB = 1024 * 1024;
+ const uintmax_t MIN_CACHE_SIZE = 256 * MB;
+ const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
+ const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
+ const F64 texture_cache_percent = 100.0 - disk_cache_percent;
+
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
- const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize");
- const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
- const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100;
- const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024;
+ const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100);
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
+ bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+
+ //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
+ remove_vfs_files = true;
}
}
@@ -4281,11 +4369,23 @@ bool LLAppViewer::initCache()
}
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
- LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
+ LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info);
if (!read_only)
{
- if (mPurgeCache)
+ if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
+ {
+ LLDiskCache::getInstance()->clearCache();
+ remove_vfs_files = true;
+ gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
+ }
+
+ if (remove_vfs_files)
+ {
+ LLDiskCache::getInstance()->removeOldVFSFiles();
+ }
+
+ if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@@ -4304,22 +4404,14 @@ bool LLAppViewer::initCache()
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
// Init the texture cache
- // Allocate 80% of the cache size for textures
- const S32 MB = 1024 * 1024;
- const S64 MIN_CACHE_SIZE = 256 * MB;
- const S64 MAX_CACHE_SIZE = 9984ll * MB;
-
- S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
- cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ // Allocate the remaining percent which is not allocated to the disk cache
+ const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100);
- S64 texture_cache_size = cache_size;
-
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- texture_cache_size -= extra;
+ LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
- return true;
+ return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
@@ -4812,13 +4904,18 @@ void LLAppViewer::idle()
}
}
+
+ // Update layonts, handle mouse events, tooltips, e t c
+ // updateUI() needs to be called even in case viewer disconected
+ // since related notification still needs handling and allows
+ // opening chat.
+ gViewerWindow->updateUI();
+
if (gDisconnected)
{
return;
}
- gViewerWindow->updateUI();
-
if (gTeleportDisplay)
{
return;
@@ -4996,8 +5093,7 @@ void LLAppViewer::idle()
audio_update_wind(false);
// this line actually commits the changes we've made to source positions, etc.
- const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
- gAudiop->idle(max_audio_decode_time);
+ gAudiop->idle();
}
}
@@ -5358,7 +5454,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
- if (LLSelectMgr::getInstance())
+ if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 68c04d450b..3888fa8ae3 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -106,6 +106,7 @@ public:
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
bool isUpdaterMissing(); // In use by tests
+ bool waitForUpdater();
void writeDebugInfo(bool isStatic=true);
@@ -129,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
+ static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@@ -152,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@@ -390,7 +392,6 @@ extern BOOL gDisconnected;
extern LLFrameTimer gRestoreGLTimer;
extern BOOL gRestoreGL;
extern bool gUseWireframe;
-extern bool gInitialDeferredModeForWireframe;
extern LLMemoryInfo gSysMemory;
extern U64Bytes gMemoryAllocated;
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index 4b6c855bde..1846238d93 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -34,6 +34,7 @@
#include "llmutelist.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
+#include "llvoavatarself.h"
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
@@ -141,11 +142,36 @@ void LLAudioSourceVO::updateMute()
LLVector3d pos_global = getPosGlobal();
F32 cutoff = mObjectp->getSoundCutOffRadius();
- if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off
- || !LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
- {
- mute = true;
- }
+ // Object can specify radius at which it turns off
+ // consider cutoff below 0.1m as 'cutoff off'
+ if (cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff))
+ {
+ mute = true;
+ }
+ // check if parcel allows sounds to pass border
+ else if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
+ {
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ // Check if agent is riding this object
+ // Agent can ride something out of region border and canHearSound
+ // will treat object as not being part of agent's parcel.
+ LLViewerObject *sound_root = (LLViewerObject*)mObjectp->getRoot();
+ LLViewerObject *agent_root = (LLViewerObject*)gAgentAvatarp->getRoot();
+ if (sound_root != agent_root)
+ {
+ mute = true;
+ }
+ else
+ {
+ LL_INFOS() << "roots identical" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mute = true;
+ }
+ }
if (!mute)
{
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1797d2dd6e..3e450e6dec 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
+#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
+#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
+#include "llviewernetwork.h" //LLGridManager
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@@ -74,6 +78,7 @@
#include "llsidepanelinventory.h"
#include "llavatarname.h"
#include "llagentui.h"
+#include "lluiusage.h"
// Flags for kick message
const U32 KICK_FLAGS_DEFAULT = 0x0;
@@ -81,6 +86,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
+std::string getProfileURL(const std::string& agent_name, bool feed_only)
+{
+ std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
+ LLSD subs;
+ subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
+ subs["AGENT_NAME"] = agent_name;
+ subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLStringUtil::toLower(url);
+ return url;
+}
+
+
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@@ -96,7 +114,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
payload["id"] = id;
payload["name"] = name;
- LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+ LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
// add friend to recent people list
LLRecentPeople::instance().add(id);
@@ -316,57 +334,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
-static const char* get_profile_floater_name(const LLUUID& avatar_id)
+// static
+void LLAvatarActions::showProfile(const LLUUID& avatar_id)
{
- // Use different floater XML for our profile to be able to save its rect.
- return avatar_id == gAgentID ? "my_profile" : "profile";
+ if (avatar_id.notNull())
+ {
+ LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+ }
}
-static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
+// static
+void LLAvatarActions::showPicks(const LLUUID& avatar_id)
{
- std::string url = getProfileURL(av_name.getAccountName());
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick();
+ }
+ }
+}
- // PROFILES: open in webkit window
- LLFloaterWebContent::Params p;
- p.url(url).id(agent_id.asString());
- LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
+// static
+void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick(pick_id);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createPick()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ LLViewerRegion* region = gAgent.getRegion();
+ if (profilefloater && region)
+ {
+ LLPickData data;
+ data.pos_global = gAgent.getPositionGlobal();
+ data.sim_name = region->getName();
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ data.name = parcel->getName();
+ data.desc = parcel->getDesc();
+ data.snapshot_id = parcel->getSnapshotID();
+ data.parcel_id = parcel->getID();
+ }
+ else
+ {
+ data.name = region->getName();
+ }
+
+ profilefloater->createPick(data);
+ }
}
// static
-void LLAvatarActions::showProfile(const LLUUID& id)
+bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
{
- if (id.notNull())
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ if (profilefloater)
+ {
+ return profilefloater->isPickTabSelected();
+ }
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
+{
+ if (avatar_id.notNull())
{
- LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified(classified_id, edit);
+ }
}
}
+// static
+void LLAvatarActions::createClassified()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ if (profilefloater)
+ {
+ profilefloater->createClassified();
+ }
+}
+
//static
-bool LLAvatarActions::profileVisible(const LLUUID& id)
+bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- return browser && browser->isShown();
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ return floater && floater->isShown();
}
//static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
+LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
- LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
- (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
- return browser;
+ LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ return floater;
}
//static
-void LLAvatarActions::hideProfile(const LLUUID& id)
+void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- if (browser)
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ if (floater)
{
- browser->closeFloater();
+ floater->closeFloater();
}
}
@@ -990,7 +1095,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
-void LLAvatarActions::toggleBlock(const LLUUID& id)
+bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1000,10 +1105,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
+ return false;
}
else
{
LLMuteList::getInstance()->add(mute);
+ return true;
}
}
@@ -1312,6 +1419,8 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo
void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
{
const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ LLUIUsage::instance().logCommand("Agent.SendFriendRequest");
+
send_improved_im(target_id,
target_name,
message,
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 7c721076c8..86183cc119 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
+std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
- /**
- * Show avatar profile.
- */
- static void showProfile(const LLUUID& id);
- static void hideProfile(const LLUUID& id);
- static bool profileVisible(const LLUUID& id);
- static LLFloater* getProfileFloater(const LLUUID& id);
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& avatar_id);
+ static void showPicks(const LLUUID& avatar_id);
+ static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
+ static void createPick();
+ static void showClassifieds(const LLUUID& avatar_id);
+ static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
+ static void createClassified();
+ static void hideProfile(const LLUUID& avatar_id);
+ static bool profileVisible(const LLUUID& avatar_id);
+ static bool isPickTabSelected(const LLUUID& avatar_id);
+ static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
- * Block/unblock the avatar.
+ * Block/unblock the avatar by id.
+ * Returns true if blocked, returns false if unblocked
*/
- static void toggleBlock(const LLUUID& id);
+ static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index b0715a3afd..c0990d9d11 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
-void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
-{
- LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
- LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
- item->setAvatarId(item_id, session_id, true, false);
- item->setName(item_name);
- item->showLastInteractionTime(mShowLastInteractionTime);
- item->showSpeakingIndicator(mShowSpeakingIndicator);
- item->setOnline(false);
-
- addItem(item, item_id);
- mIDs.push_back(item_id);
- sort();
-}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
- if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
- {
- const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
- addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
- }
- else
- {
- std::string display_name = getAvatarName(av_name);
- addNewItem(buddy_id,
- display_name.empty() ? waiting_str : display_name,
- LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::string display_name = getAvatarName(av_name);
+ addNewItem(buddy_id,
+ display_name.empty() ? waiting_str : display_name,
+ LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- if ( mContextMenu && !isAvalineItemSelected())
+ if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
-bool LLAvatarList::isAvalineItemSelected()
-{
- std::vector<LLPanel*> selected_items;
- getSelectedItems(selected_items);
- std::vector<LLPanel*>::iterator it = selected_items.begin();
-
- for(; it != selected_items.end(); ++it)
- {
- if (dynamic_cast<LLAvalineListItem*>(*it))
- return true;
- }
-
- return false;
-}
-
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
-
-/************************************************************************/
-/* class LLAvalineListItem */
-/************************************************************************/
-LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
-, mIsHideNumber(hide_number)
-{
- // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
- buildFromFile( "panel_avatar_list_item.xml");
-}
-
-BOOL LLAvalineListItem::postBuild()
-{
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
-}
-
-// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
-void LLAvalineListItem::setName(const std::string& name)
-{
- if (mIsHideNumber)
- {
- static U32 order = 0;
- typedef std::map<LLUUID, U32> avaline_callers_nums_t;
- static avaline_callers_nums_t mAvalineCallersNums;
-
- llassert(getAvatarId() != LLUUID::null);
-
- const LLUUID &uuid = getAvatarId();
-
- if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end())
- {
- mAvalineCallersNums[uuid] = ++order;
- LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL;
- }
- LLStringUtil::format_map_t args;
- args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]);
- std::string hidden_name = LLTrans::getString("AvalineCaller", args);
-
- LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL;
- LLAvatarListItem::setAvatarName(hidden_name);
- LLAvatarListItem::setAvatarToolTip(hidden_name);
- }
- else
- {
- const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
- LLAvatarListItem::setAvatarName(formatted_phone);
- LLAvatarListItem::setAvatarToolTip(formatted_phone);
- }
-}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 1a672c279b..48b0e70454 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
- void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@@ -118,8 +117,6 @@ protected:
private:
- bool isAvalineItemSelected();
-
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
-/**
- * Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
- */
-class LLAvalineListItem : public LLAvatarListItem
-{
-public:
-
- /**
- * Constructor
- *
- * @param hide_number - flag indicating if number should be hidden.
- * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
- */
- LLAvalineListItem(bool hide_number = true);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setName(const std::string& name);
-
-private:
- bool mIsHideNumber;
-};
-
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f41eb3daf4..dd0d06a8c8 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
+#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
-
-void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
+void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this messages won't work so don't bother trying
+ if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
+ {
+ return;
+ }
+
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
- // indicate we're going to make a request
- addPendingRequest(avatar_id, type);
- std::vector<std::string> strings;
- strings.push_back( avatar_id.asString() );
- send_generic_message(method, strings);
+ std::string cap;
+
+ switch (type)
+ {
+ case APT_PROPERTIES:
+ // indicate we're going to make a request
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ // can use getRegionCapability("AgentProfile"), but it is heavy
+ // initAgentProfileCapRequest(avatar_id, cap);
+ break;
+ case APT_PICKS:
+ case APT_GROUPS:
+ case APT_NOTES:
+ if (cap.empty())
+ {
+ // indicate we're going to make a request
+ sendGenericRequest(avatar_id, type, method);
+ }
+ else
+ {
+ initAgentProfileCapRequest(avatar_id, cap);
+ }
+ break;
+ default:
+ sendGenericRequest(avatar_id, type, method);
+ break;
+ }
}
-void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the AvatarPropertiesRequest message
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
- {
- return;
- }
+ // indicate we're going to make a request
+ addPendingRequest(avatar_id, type);
- if (isPendingRequest(avatar_id, APT_PROPERTIES))
- {
- // waiting for a response, don't re-request
- return;
- }
- // indicate we're going to make a request
- addPendingRequest(avatar_id, APT_PROPERTIES);
+ std::vector<std::string> strings;
+ strings.push_back(avatar_id.asString());
+ send_generic_message(method, strings);
+}
- LLMessageSystem *msg = gMessageSystem;
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
- gAgent.sendReliableMessage();
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PICKS);
+ addPendingRequest(avatar_id, APT_GROUPS);
+ addPendingRequest(avatar_id, APT_NOTES);
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+{
+ sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
+ sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
- LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
+ LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
+// static
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->removePendingRequest(agent_id, APT_NOTES);
+ return;
+ }
+
+ // Avatar Data
+
+ LLAvatarData avatar_data;
+ std::string birth_date;
+
+ avatar_data.agent_id = agent_id;
+ avatar_data.avatar_id = agent_id;
+ avatar_data.image_id = result["sl_image_id"].asUUID();
+ avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data.partner_id = result["partner_id"].asUUID();
+ avatar_data.about_text = result["sl_about_text"].asString();
+ avatar_data.fl_about_text = result["fl_about_text"].asString();
+ avatar_data.born_on = result["member_since"].asDate();
+ avatar_data.profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data.flags = 0;
+ avatar_data.caption_index = 0;
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_NOTES);
+ self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
+
+ LLInterestsData interests_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
+ self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
+void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
+{
+ if(!interests_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_AvatarInterestsUpdate);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast( _PREHASH_PropertiesData);
+ msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
+ msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
+ msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
+ msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
+ msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index b063048c26..f778634d25 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
+ APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
+struct LLInterestsData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ U32 want_to_mask;
+ std::string want_to_text;
+ U32 skills_mask;
+ std::string skills_text;
+ std::string languages_text;
+};
+
struct LLAvatarData
{
LLUUID agent_id;
@@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
+ void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@@ -252,7 +268,10 @@ public:
protected:
- void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index fe94cd27b6..275f17b02a 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
// make sure we won't re-report, coro will update timer with correct time later
regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ try
+ {
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
@@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// make sure we won't re-request, coro will update timer with correct time later
regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
- // First send a request to get the latest data
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ try
+ {
+ // First send a request to get the latest data
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 8d1e9a438e..1ad2157df0 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -53,6 +53,7 @@
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "llavataractions.h"
+#include "lluiusage.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -294,6 +295,8 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const
void LLAvatarTracker::terminateBuddy(const LLUUID& id)
{
LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Agent.TerminateFriendship");
+
LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id);
if(!buddy) return;
mBuddyInfo.erase(id);
@@ -640,6 +643,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
+ mChangedBuddyIDs.insert(agent_related);
}
}
else
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index e400609a74..72f667a0b8 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -568,8 +568,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
- LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
-
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index cdf82c77c1..7ff24f64ac 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
+ mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
+ else if (level == "report_abuse")
+ {
+ std::string time_string;
+ if (mTime > 0) // have frame time
+ {
+ time_t current_time = time_corrected();
+ time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
+
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32)message_time;
+ LLStringUtil::format(time_string, substitution);
+ }
+ else
+ {
+ // From history. This might be empty or not full.
+ // See LLChatLogParser::parse
+ time_string = getChild<LLTextBox>("time_box")->getValue().asString();
+
+ // Just add current date if not full.
+ // Should be fine since both times are supposed to be stl
+ if (!time_string.empty() && time_string.size() < 7)
+ {
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] " + time_string;
+
+ LLSD substitution;
+ // To avoid adding today's date to yesterday's timestamp,
+ // use creation time instead of current time
+ substitution["datetime"] = (S32)mCreationTime;
+ LLStringUtil::format(time_string, substitution);
+ }
+ }
+ LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
+ }
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
+ else if (level == "report_abuse")
+ {
+ return gAgentID != mAvatarID;
+ }
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@@ -558,9 +606,15 @@ public:
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());
- llassert(mInfoCtrl != NULL);
- mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
- mInfoCtrl->setVisible(FALSE);
+ if (mInfoCtrl)
+ {
+ mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
+ mInfoCtrl->setVisible(FALSE);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create an interface element due to missing or corrupted file inspector_info_ctrl.xml" << LL_ENDL;
+ }
return LLPanel::postBuild();
}
@@ -628,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
+ // To be able to report a message, we need a copy of it's text
+ // and it's easier to store text directly than trying to get
+ // it from a lltextsegment or chat's mEditor
+ mText = chat.mText;
+ mTime = chat.mTime;
+
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@@ -977,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
+ std::string mText;
+ F64 mTime; // IM's frame time
+ time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 80d810d159..036ff17074 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
pickerp->getCurG (),
pickerp->getCurB (),
subject->mColor.mV[VALPHA] ); // keep current alpha
- subject->mColor = updatedColor;
- subject->setControlValue(updatedColor.getValue());
- pickerp->setRevertOnCancel(TRUE);
+
+ bool color_changed = subject->mColor != updatedColor;
+ if (color_changed)
+ {
+ subject->mColor = updatedColor;
+ subject->setControlValue(updatedColor.getValue());
+ }
+
if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
{
subject->mOnCancelCallback( subject, LLSD());
@@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
// just commit change
subject->onCommit ();
}
+
+ if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT)
+ {
+ // both select and cancel close LLFloaterColorPicker
+ // but COLOR_CHANGE does not
+ subject->setFocus(TRUE);
+ }
}
}
}
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 4a87273372..d4d4f641cf 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -610,6 +610,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -627,7 +628,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
{
LLVector4a local_end = end;
LLVector4a local_intersection;
- if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -644,7 +645,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
{
LLVOVolume *volp = *vol_it;
- if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 8e87299f3e..ea91d70e69 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -68,6 +68,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 86e23e7c83..97b16a5e93 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
- "can_pay" == command_name)
+ "can_pay" == command_name ||
+ "report_abuse" == command_name)
{
return is_p2p;
}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a685639427..9ec4fb085b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
+ items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 20fa6d490b..48c7df40df 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -272,9 +272,9 @@ BOOL LLConversationViewSession::postBuild()
default:
break;
}
- }
- refresh();
+ refresh(); // requires vmi
+ }
return TRUE;
}
@@ -490,17 +490,20 @@ void LLConversationViewSession::refresh()
{
// Refresh the session view from its model data
LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
- vmi->resetRefresh();
+ if (vmi)
+ {
+ vmi->resetRefresh();
- if (mSessionTitle)
- {
- if (!highlightFriendTitle(vmi))
- {
- LLStyle::Params title_style;
- title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
- mSessionTitle->setText(vmi->getDisplayName(), title_style);
- }
- }
+ if (mSessionTitle)
+ {
+ if (!highlightFriendTitle(vmi))
+ {
+ LLStyle::Params title_style;
+ title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+ mSessionTitle->setText(vmi->getDisplayName(), title_style);
+ }
+ }
+ }
// Update all speaking indicators
LLSpeakingIndicatorManager::updateSpeakingIndicators();
@@ -524,8 +527,11 @@ void LLConversationViewSession::refresh()
}
requestArrange();
- // Do the regular upstream refresh
- LLFolderViewFolder::refresh();
+ if (vmi)
+ {
+ // Do the regular upstream refresh
+ LLFolderViewFolder::refresh();
+ }
}
void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
@@ -627,8 +633,11 @@ BOOL LLConversationViewParticipant::postBuild()
}
updateChildren();
- LLFolderViewItem::postBuild();
- refresh();
+ if (getViewModelItem())
+ {
+ LLFolderViewItem::postBuild();
+ refresh();
+ }
return TRUE;
}
@@ -712,10 +721,10 @@ void LLConversationViewParticipant::refresh()
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+
+ // Do the regular upstream refresh
+ LLFolderViewItem::refresh();
}
-
- // Do the regular upstream refresh
- LLFolderViewItem::refresh();
}
void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7d4961c598..4d9ef99319 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
{
}
+void LLDoNotDisturbNotificationStorage::reset()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+}
+
void LLDoNotDisturbNotificationStorage::initialize()
{
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+ reset();
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index c6f0bf1ab5..237d58b4de 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
+ void reset();
protected:
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 4a0c9d399f..74625423fe 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -249,12 +249,9 @@ void LLDrawable::cleanupReferences()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
- gObjectList.removeDrawable(this);
-
gPipeline.unlinkDrawable(this);
removeFromOctree();
@@ -885,7 +882,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
LLFace* facep = getFace(i);
if (facep &&
- (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
+ (force_update || facep->isInAlphaPool()))
{
LLVector4a box;
box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -1255,7 +1252,7 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
LLDrawable(root->getVObj(), true),
- LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
+ LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW, regionp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2372ea01a6..2a0f4c93ac 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -133,6 +133,7 @@ public:
inline LLFace* getFace(const S32 i) const;
inline S32 getNumFaces() const;
face_list_t& getFaces() { return mFaces; }
+ const face_list_t& getFaces() const { return mFaces; }
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index a3837fe10c..7305177e4a 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -37,6 +37,7 @@
#include "lldrawpoolbump.h"
#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
+#include "lldrawpoolpbropaque.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
#include "lldrawpooltree.h"
@@ -85,9 +86,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GLOW:
poolp = new LLDrawPoolGlow();
break;
- case POOL_ALPHA:
- poolp = new LLDrawPoolAlpha();
+ case POOL_ALPHA_PRE_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER);
break;
+ case POOL_ALPHA_POST_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_POST_WATER);
+ break;
case POOL_AVATAR:
case POOL_CONTROL_AV:
poolp = new LLDrawPoolAvatar(type);
@@ -117,6 +121,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
+ case POOL_PBR_OPAQUE:
+ poolp = new LLDrawPoolPBROpaque();
+ break;
default:
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
return NULL;
@@ -207,15 +214,6 @@ void LLDrawPool::renderPostDeferred(S32 pass)
//virtual
void LLDrawPool::endRenderPass( S32 pass )
{
- /*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
- }
- }*/
-
//make sure channel 0 is active channel
gGL.getTexUnit(0)->activate();
}
@@ -573,7 +571,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
params.mGroup->rebuildMesh();
}
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ LLGLDisable cull(params.mGLTFMaterial && params.mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
+
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index fd1b022e5b..620438bb1b 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -48,25 +48,33 @@ public:
enum
{
// Correspond to LLPipeline render type
+ // Also controls render order, so passes that don't use alpha masking/blending should come before
+ // other passes to preserve hierarchical Z for occlusion queries. Occlusion queries happen just
+ // before grass, so grass should be the first alpha masked pool. Other ordering should be done
+ // based on fill rate and likelihood to occlude future passes (faster, large occluders first).
+ //
POOL_SIMPLE = 1,
POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
- POOL_MATERIALS,
- POOL_TERRAIN,
- POOL_SKY,
- POOL_WL_SKY,
+ POOL_TERRAIN,
+ POOL_MATERIALS,
+ POOL_GRASS,
POOL_TREE,
POOL_ALPHA_MASK,
POOL_FULLBRIGHT_ALPHA_MASK,
- POOL_GRASS,
+ POOL_SKY,
+ POOL_WL_SKY,
POOL_INVISIBLE, // see below *
POOL_AVATAR,
POOL_CONTROL_AV, // Animesh
- POOL_VOIDWATER,
- POOL_WATER,
POOL_GLOW,
- POOL_ALPHA,
+ POOL_ALPHA_PRE_WATER,
+ POOL_VOIDWATER,
+ POOL_WATER,
+ POOL_ALPHA_POST_WATER,
+ POOL_PBR_OPAQUE,
+ POOL_ALPHA, // note there is no actual "POOL_ALPHA" but pre-water and post-water pools consume POOL_ALPHA faces
NUM_POOL_TYPES,
// * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them
// - and the LLDrawPool types enum controls what order things are rendered in
@@ -129,6 +137,7 @@ class LLRenderPass : public LLDrawPool
public:
// list of possible LLRenderPass types to assign a render batch to
// NOTE: "rigged" variant MUST be non-rigged variant + 1
+ // see LLVolumeGeometryManager::registerFace()
enum
{
PASS_SIMPLE = NUM_POOL_TYPES,
@@ -190,9 +199,147 @@ public:
PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
PASS_ALPHA_INVISIBLE,
PASS_ALPHA_INVISIBLE_RIGGED,
+ PASS_PBR_OPAQUE,
+ PASS_PBR_OPAQUE_RIGGED,
NUM_RENDER_TYPES,
};
+ #ifdef LL_PROFILER_ENABLE_TRACY_OPENGL
+ static inline const char* lookupPassName(U32 pass)
+ {
+ switch (pass)
+ {
+ case PASS_SIMPLE:
+ return "PASS_SIMPLE";
+ case PASS_SIMPLE_RIGGED:
+ return "PASS_SIMPLE_RIGGED";
+ case PASS_GRASS:
+ return "PASS_GRASS";
+ case PASS_FULLBRIGHT:
+ return "PASS_FULLBRIGHT";
+ case PASS_FULLBRIGHT_RIGGED:
+ return "PASS_FULLBRIGHT_RIGGED";
+ case PASS_INVISIBLE:
+ return "PASS_INVISIBLE";
+ case PASS_INVISIBLE_RIGGED:
+ return "PASS_INVISIBLE_RIGGED";
+ case PASS_INVISI_SHINY:
+ return "PASS_INVISI_SHINY";
+ case PASS_INVISI_SHINY_RIGGED:
+ return "PASS_INVISI_SHINY_RIGGED";
+ case PASS_FULLBRIGHT_SHINY:
+ return "PASS_FULLBRIGHT_SHINY";
+ case PASS_FULLBRIGHT_SHINY_RIGGED:
+ return "PASS_FULLBRIGHT_SHINY_RIGGED";
+ case PASS_SHINY:
+ return "PASS_SHINY";
+ case PASS_SHINY_RIGGED:
+ return "PASS_SHINY_RIGGED";
+ case PASS_BUMP:
+ return "PASS_BUMP";
+ case PASS_BUMP_RIGGED:
+ return "PASS_BUMP_RIGGED";
+ case PASS_POST_BUMP:
+ return "PASS_POST_BUMP";
+ case PASS_POST_BUMP_RIGGED:
+ return "PASS_POST_BUMP_RIGGED";
+ case PASS_MATERIAL:
+ return "PASS_MATERIAL";
+ case PASS_MATERIAL_RIGGED:
+ return "PASS_MATERIAL_RIGGED";
+ case PASS_MATERIAL_ALPHA:
+ return "PASS_MATERIAL_ALPHA";
+ case PASS_MATERIAL_ALPHA_RIGGED:
+ return "PASS_MATERIAL_ALPHA_RIGGED";
+ case PASS_MATERIAL_ALPHA_MASK:
+ return "PASS_MATERIAL_ALPHA_MASK";
+ case PASS_MATERIAL_ALPHA_MASK_RIGGED:
+ return "PASS_MATERIAL_ALPHA_MASK_RIGGED";
+ case PASS_MATERIAL_ALPHA_EMISSIVE:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE";
+ case PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED";
+ case PASS_SPECMAP:
+ return "PASS_SPECMAP";
+ case PASS_SPECMAP_RIGGED:
+ return "PASS_SPECMAP_RIGGED";
+ case PASS_SPECMAP_BLEND:
+ return "PASS_SPECMAP_BLEND";
+ case PASS_SPECMAP_BLEND_RIGGED:
+ return "PASS_SPECMAP_BLEND_RIGGED";
+ case PASS_SPECMAP_MASK:
+ return "PASS_SPECMAP_MASK";
+ case PASS_SPECMAP_MASK_RIGGED:
+ return "PASS_SPECMAP_MASK_RIGGED";
+ case PASS_SPECMAP_EMISSIVE:
+ return "PASS_SPECMAP_EMISSIVE";
+ case PASS_SPECMAP_EMISSIVE_RIGGED:
+ return "PASS_SPECMAP_EMISSIVE_RIGGED";
+ case PASS_NORMMAP:
+ return "PASS_NORMAMAP";
+ case PASS_NORMMAP_RIGGED:
+ return "PASS_NORMMAP_RIGGED";
+ case PASS_NORMMAP_BLEND:
+ return "PASS_NORMMAP_BLEND";
+ case PASS_NORMMAP_BLEND_RIGGED:
+ return "PASS_NORMMAP_BLEND_RIGGED";
+ case PASS_NORMMAP_MASK:
+ return "PASS_NORMMAP_MASK";
+ case PASS_NORMMAP_MASK_RIGGED:
+ return "PASS_NORMMAP_MASK_RIGGED";
+ case PASS_NORMMAP_EMISSIVE:
+ return "PASS_NORMMAP_EMISSIVE";
+ case PASS_NORMMAP_EMISSIVE_RIGGED:
+ return "PASS_NORMMAP_EMISSIVE_RIGGED";
+ case PASS_NORMSPEC:
+ return "PASS_NORMSPEC";
+ case PASS_NORMSPEC_RIGGED:
+ return "PASS_NORMSPEC_RIGGED";
+ case PASS_NORMSPEC_BLEND:
+ return "PASS_NORMSPEC_BLEND";
+ case PASS_NORMSPEC_BLEND_RIGGED:
+ return "PASS_NORMSPEC_BLEND_RIGGED";
+ case PASS_NORMSPEC_MASK:
+ return "PASS_NORMSPEC_MASK";
+ case PASS_NORMSPEC_MASK_RIGGED:
+ return "PASS_NORMSPEC_MASK_RIGGED";
+ case PASS_NORMSPEC_EMISSIVE:
+ return "PASS_NORMSPEC_EMISSIVE";
+ case PASS_NORMSPEC_EMISSIVE_RIGGED:
+ return "PASS_NORMSPEC_EMISSIVE_RIGGED";
+ case PASS_GLOW:
+ return "PASS_GLOW";
+ case PASS_GLOW_RIGGED:
+ return "PASS_GLOW_RIGGED";
+ case PASS_ALPHA:
+ return "PASS_ALPHA";
+ case PASS_ALPHA_RIGGED:
+ return "PASS_ALPHA_RIGGED";
+ case PASS_ALPHA_MASK:
+ return "PASS_ALPHA_MASK";
+ case PASS_ALPHA_MASK_RIGGED:
+ return "PASS_ALPHA_MASK_RIGGED";
+ case PASS_FULLBRIGHT_ALPHA_MASK:
+ return "PASS_FULLBRIGHT_ALPHA_MASK";
+ case PASS_FULLBRIGHT_ALPHA_MASK_RIGGED:
+ return "PASS_FULLBRIGHT_ALPHA_MASK_RIGGED";
+ case PASS_ALPHA_INVISIBLE:
+ return "PASS_ALPHA_INVISIBLE";
+ case PASS_ALPHA_INVISIBLE_RIGGED:
+ return "PASS_ALPHA_INVISIBLE_RIGGED";
+ case PASS_PBR_OPAQUE:
+ return "PASS_PBR_OPAQUE";
+ case PASS_PBR_OPAQUE_RIGGED:
+ return "PASS_PBR_OPAQUE_RIGGED";
+
+ default:
+ return "Unknown pass";
+ }
+ }
+ #else
+ static inline const char* lookupPass(U32 pass) { return ""; }
+ #endif
+
LLRenderPass(const U32 type);
virtual ~LLRenderPass();
/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e674707c01..aa8d4d167e 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -50,14 +50,19 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
+#include "llenvironment.h"
+
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
+LLVector4 LLDrawPoolAlpha::sWaterPlane;
+
static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
+
// minimum alpha before discarding a fragment when rendering impostors
static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
@@ -81,6 +86,11 @@ void LLDrawPoolAlpha::prerender()
// TODO: is this even necessay? These are probably set to never discard
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
+
+ if (LLPipeline::sRenderPBR)
+ {
+ gPipeline.setupHWLights(NULL);
+ }
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -89,11 +99,13 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
}
// set some common parameters on the given shader to prepare for alpha rendering
-static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment, F32 water_sign)
{
static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
F32 gamma = displayGamma;
+ static LLStaticHashedString waterSign("waterSign");
+
// Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
// NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
// TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
@@ -108,6 +120,8 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
}
shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+ shader->uniform1f(waterSign, water_sign);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
if (LLPipeline::sImpostorRender)
{
@@ -125,28 +139,54 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
{
- prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
+extern BOOL gCubeSnapshot;
+
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ if ((!LLPipeline::sRenderTransparentWater || gCubeSnapshot) && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ { // don't render alpha objects on the other side of the water plane if water is opaque
+ return;
+ }
deferred_render = TRUE;
+ F32 water_sign = 1.f;
+
+ if (getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ {
+ water_sign = -1.f;
+ }
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ water_sign *= -1.f;
+ }
+
// prepare shaders
emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
(LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- prepare_alpha_shader(emissive_shader, true, false);
+ prepare_alpha_shader(emissive_shader, true, false, water_sign);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
- prepare_alpha_shader(fullbright_shader, true, false);
+ prepare_alpha_shader(fullbright_shader, true, true, water_sign);
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
- prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
+ LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+ for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ prepare_alpha_shader(&materialShader[i], false, false, water_sign);
+ }
+
+ prepare_alpha_shader(&gDeferredPBRAlphaProgram, false, false, water_sign);
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
@@ -155,13 +195,13 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
forwardRender();
// final pass, render to depth for depth of field effects
- if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+ if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot)
{
//update depth buffer sampler
- gPipeline.mScreen.flush();
- gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
- 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- gPipeline.mDeferredDepth.bindTarget();
+ /*gPipeline.mRT->screen.flush();
+ gPipeline.mRT->deferredDepth.copyContents(gPipeline.mRT->deferredScreen, 0, 0, gPipeline.mRT->deferredScreen.getWidth(), gPipeline.mRT->deferredScreen.getHeight(),
+ 0, 0, gPipeline.mRT->deferredDepth.getWidth(), gPipeline.mRT->deferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ gPipeline.mRT->deferredDepth.bindTarget();*/
simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
simple_shader->bind();
@@ -175,8 +215,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
true); // <--- discard mostly transparent faces
- gPipeline.mDeferredDepth.flush();
- gPipeline.mScreen.bindTarget();
+ //gPipeline.mRT->deferredDepth.flush();
+ //gPipeline.mRT->screen.bindTarget();
gGL.setColorMask(true, false);
}
@@ -215,9 +255,15 @@ void LLDrawPoolAlpha::render(S32 pass)
{
minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
}
+
prepare_forward_shader(fullbright_shader, minimum_alpha);
prepare_forward_shader(simple_shader, minimum_alpha);
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha);
+ }
+
//first pass -- rigged only and drawn to depth buffer
forwardRender(true);
@@ -396,62 +442,76 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
{
bool tex_setup = false;
- if (deferred_render && use_material && current_shader)
+ if (draw->mGLTFMaterial)
{
- if (draw->mNormalMap)
- {
- draw->mNormalMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
- }
-
- if (draw->mSpecularMap)
- {
- draw->mSpecularMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
- }
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
}
- else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ else
{
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
- if (draw->mTextureList.size() > 1)
- {
- for (U32 i = 0; i < draw->mTextureList.size(); ++i)
- {
- if (draw->mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (draw->mTexture.notNull())
- {
- if (use_material)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bindFast(draw->mTexture);
- }
+ if (deferred_render && use_material && current_shader)
+ {
+ if (draw->mNormalMap)
+ {
+ draw->mNormalMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
- if (draw->mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
+ if (draw->mSpecularMap)
+ {
+ draw->mSpecularMap->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+ else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ {
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ if (use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(draw->mTexture);
+ }
+
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
return tex_setup;
}
@@ -600,94 +660,117 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
}
- LLRenderPass::applyModelMatrix(params);
+ LLRenderPass::applyModelMatrix(params);
- LLMaterial* mat = NULL;
+ LLMaterial* mat = NULL;
+ LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; // Also see: LLPipeline::getPoolTypeFromTE()
+ bool is_pbr = LLPipeline::sRenderPBR && gltf_mat;
- if (deferred_render)
- {
- mat = params.mMaterial;
- }
-
- if (params.mFullbright)
- {
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = fullbright_shader;
+ LLGLDisable cull_face(is_pbr && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0);
- light_enabled = FALSE;
- }
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = simple_shader;
- light_enabled = TRUE;
- }
+ if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ target_shader = &gDeferredPBRAlphaProgram;
+ if (params.mAvatar != nullptr)
+ {
+ target_shader = target_shader->mRiggedVariant;
+ }
- if (deferred_render && mat)
- {
- U32 mask = params.mShaderMask;
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = &(gDeferredMaterialProgram[mask]);
+ params.mGLTFMaterial->bind(target_shader);
+ }
+ else
+ {
+ if (deferred_render)
+ {
+ mat = params.mMaterial;
+ }
+
+ if (params.mFullbright)
+ {
+ // Turn off lighting if it hasn't already been so.
+ if (light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = fullbright_shader;
+
+ light_enabled = FALSE;
+ }
+ }
+ // Turn on lighting if it isn't already.
+ else if (!light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = simple_shader;
+ light_enabled = TRUE;
+ }
+
+ if (deferred_render && mat)
+ {
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+
+ if (params.mAvatar != nullptr)
+ {
+ llassert(target_shader->mRiggedVariant != nullptr);
+ target_shader = target_shader->mRiggedVariant;
+ }
+
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
- if (LLPipeline::sUnderWaterRender)
- {
- target_shader = &(gDeferredMaterialWaterProgram[mask]);
- }
if (params.mAvatar != nullptr)
{
- llassert(target_shader->mRiggedVariant != nullptr);
target_shader = target_shader->mRiggedVariant;
}
- if (current_shader != target_shader)
- {
- gPipeline.bindDeferredShader(*target_shader);
- }
- }
- else if (!params.mFullbright)
- {
- target_shader = simple_shader;
- }
- else
- {
- target_shader = fullbright_shader;
- }
-
- if (params.mAvatar != nullptr)
- {
- target_shader = target_shader->mRiggedVariant;
- }
-
- if (current_shader != target_shader)
- {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- target_shader->bind();
- }
+ if (current_shader != target_shader)
+ {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
+ // (this way we won't rebind shaders unnecessarily).
+ gPipeline.bindDeferredShader(*target_shader);
+ }
- LLVector4 spec_color(1, 1, 1, 1);
- F32 env_intensity = 0.0f;
- F32 brightness = 1.0f;
+ LLVector4 spec_color(1, 1, 1, 1);
+ F32 env_intensity = 0.0f;
+ F32 brightness = 1.0f;
- // We have a material. Supply the appropriate data here.
- if (mat && deferred_render)
- {
- spec_color = params.mSpecColor;
- env_intensity = params.mEnvIntensity;
- brightness = params.mFullbright ? 1.f : 0.f;
- }
+ // We have a material. Supply the appropriate data here.
+ if (mat && deferred_render)
+ {
+ spec_color = params.mSpecColor;
+ env_intensity = params.mEnvIntensity;
+ brightness = params.mFullbright ? 1.f : 0.f;
+ }
- if (current_shader)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ if (current_shader)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ }
}
if (params.mGroup)
@@ -714,7 +797,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
bool tex_setup = TexSetup(&params, (mat != nullptr));
{
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index fa8ef0f227..2c1ec30958 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -35,9 +35,13 @@ class LLFace;
class LLColor4;
class LLGLSLShader;
-class LLDrawPoolAlpha: public LLRenderPass
+class LLDrawPoolAlpha final: public LLRenderPass
{
public:
+
+ // set by llsettingsvo so lldrawpoolalpha has quick access to the water plane in eye space
+ static LLVector4 sWaterPlane;
+
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
@@ -47,7 +51,7 @@ public:
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
+ LLDrawPoolAlpha(U32 type);
/*virtual*/ ~LLDrawPoolAlpha();
/*virtual*/ S32 getNumPostDeferredPasses();
@@ -91,11 +95,4 @@ private:
bool mRigged = false;
};
-class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
-{
-public:
- LLDrawPoolAlphaPostWater();
- virtual void render(S32 pass = 0);
-};
-
#endif // LL_LLDRAWPOOLALPHA_H
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 4a9a3caaec..67c3000410 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -54,7 +54,7 @@
#include "llviewertexturelist.h"
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
-static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
+static U32 sBufferUsage = GL_STREAM_DRAW;
static U32 sShaderLevel = 0;
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
@@ -146,11 +146,11 @@ void LLDrawPoolAvatar::prerender()
if (sShaderLevel > 0)
{
- sBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ sBufferUsage = GL_DYNAMIC_DRAW;
}
else
{
- sBufferUsage = GL_STREAM_DRAW_ARB;
+ sBufferUsage = GL_STREAM_DRAW;
}
}
@@ -934,7 +934,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
LLVertexBufferAvatar::LLVertexBufferAvatar()
: LLVertexBuffer(sDataMask,
- GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
+ GL_STREAM_DRAW) //avatars are always stream draw due to morph targets
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 8db6a10e26..75917d0ae3 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -465,6 +465,15 @@ void LLDrawPoolBump::beginFullbrightShiny()
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
cube_map->setMatrix(1);
+ if (LLPipeline::sReflectionProbesEnabled)
+ {
+ gPipeline.bindReflectionProbes(*shader);
+ }
+ else
+ {
+ gPipeline.setEnvMat(*shader);
+ }
+
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
gGL.getTexUnit(1)->disable();
@@ -526,6 +535,10 @@ void LLDrawPoolBump::endFullbrightShiny()
{
cube_map->disable();
cube_map->restoreMatrix();
+ if (shader->mFeatures.hasReflectionProbes)
+ {
+ gPipeline.unbindReflectionProbes(*shader);
+ }
shader->unbind();
}
@@ -673,6 +686,7 @@ void LLDrawPoolBump::endBump(U32 pass)
S32 LLDrawPoolBump::getNumDeferredPasses()
{
+#if 0 //DEPRECATED -- RenderObjectBump should always be TRUE
if (gSavedSettings.getBOOL("RenderObjectBump"))
{
return 1;
@@ -681,6 +695,9 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
{
return 0;
}
+#else
+ return 1;
+#endif
}
void LLDrawPoolBump::renderDeferred(S32 pass)
@@ -741,6 +758,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL
for (int i = 0; i < 2; ++i)
{ // two passes -- static and rigged
mRigged = (i == 1);
@@ -1449,11 +1467,11 @@ void LLDrawPoolInvisible::render(S32 pass)
}
U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
- glStencilMask(0);
+ //glStencilMask(0); //deprecated
gGL.setColorMask(false, false);
pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
gGL.setColorMask(true, false);
- glStencilMask(0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF); //deprecated
if (gPipeline.shadersLoaded())
{
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 2b05f4c453..d97f0714ef 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -260,7 +260,7 @@ void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool
(GLfloat*)&(mpc.mGLMp[0]));
}
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ //LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
new file mode 100644
index 0000000000..2f710e570b
--- /dev/null
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -0,0 +1,140 @@
+/**
+ * @file lldrawpoolpbropaque.cpp
+ * @brief LLDrawPoolPBROpaque class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpool.h"
+#include "lldrawpoolpbropaque.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+LLDrawPoolPBROpaque::LLDrawPoolPBROpaque() :
+ LLRenderPass(POOL_PBR_OPAQUE)
+{
+}
+
+void LLDrawPoolPBROpaque::prerender()
+{
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+// Forward
+void LLDrawPoolPBROpaque::beginRenderPass(S32 pass)
+{
+}
+
+void LLDrawPoolPBROpaque::endRenderPass( S32 pass )
+{
+}
+
+void LLDrawPoolPBROpaque::render(S32 pass)
+{
+}
+
+void LLDrawPoolPBROpaque::renderDeferred(S32 pass)
+{
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_MATERIALS))
+ {
+ return;
+ }
+
+ const U32 type = LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE;
+ if (!gPipeline.hasRenderType(type))
+ {
+ return;
+ }
+
+ gGL.flush();
+
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable alpha_test(GL_ALPHA_TEST);
+
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = (i == 1);
+ LLGLSLShader* shader = &gDeferredPBROpaqueProgram;
+ U32 vertex_data_mask = getVertexDataMask();
+
+ if (rigged)
+ {
+ shader = shader->mRiggedVariant;
+ vertex_data_mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ shader->bind();
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type+i);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type+i);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ auto& mat = pparams->mGLTFMaterial;
+
+ mat->bind(shader);
+
+ LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+ bool tex_setup = false;
+ if (pparams->mTextureMatrix)
+ { //special case implementation of texture animation here because of special handling of textures for PBR batches
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)pparams->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+
+ if (rigged)
+ {
+ if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
+ }
+ else
+ {
+ pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
+ }
+
+ if (tex_setup)
+ {
+ gGL.matrixMode(LLRender::MM_TEXTURE0);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ }
+ }
+
+ LLGLSLShader::sCurBoundShaderPtr->unbind();
+}
diff --git a/indra/newview/lldrawpoolpbropaque.h b/indra/newview/lldrawpoolpbropaque.h
new file mode 100644
index 0000000000..c355b10b12
--- /dev/null
+++ b/indra/newview/lldrawpoolpbropaque.h
@@ -0,0 +1,63 @@
+/**
+ * @file lldrawpoolpbropaque.h
+ * @brief LLDrawPoolPBrOpaque class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLDRAWPOOLPBROPAQUE_H
+#define LL_LLDRAWPOOLPBROPAQUE_H
+
+#include "lldrawpool.h"
+
+class LLDrawPoolPBROpaque : public LLRenderPass
+{
+public:
+ enum
+ {
+ // See: DEFERRED_VB_MASK
+ VERTEX_DATA_MASK = 0
+ | LLVertexBuffer::MAP_VERTEX
+ | LLVertexBuffer::MAP_NORMAL
+ | LLVertexBuffer::MAP_TEXCOORD0 // Diffuse
+ | LLVertexBuffer::MAP_TEXCOORD1 // Normal
+ | LLVertexBuffer::MAP_TEXCOORD2 // Spec <-- ORM Occlusion Roughness Metal
+ | LLVertexBuffer::MAP_TANGENT
+ | LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolPBROpaque();
+
+ /*virtual*/ S32 getNumDeferredPasses() { return 1; }
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ // Non ALM isn't supported
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ S32 getNumPasses() { return 0; }
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+
+};
+
+#endif // LL_LLDRAWPOOLPBROPAQUE_H
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 3a1efec91b..55ebf03adc 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -51,7 +51,10 @@ LLDrawPoolSky::LLDrawPoolSky()
void LLDrawPoolSky::prerender()
{
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
- gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
+ if (gSky.mVOSkyp->mDrawable)
+ {
+ gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
+ }
}
void LLDrawPoolSky::render(S32 pass)
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index be33e1b30a..55c8d84838 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -165,19 +165,6 @@ void LLDrawPoolTerrain::render(S32 pass)
LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
- if (!gGLManager.mHasMultitexture)
- {
- // No multitexture, render simple land.
- renderSimple(); // Render without multitexture
- return;
- }
- // Render simplified land if video card can't do sufficient multitexturing
- if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
- {
- renderSimple(); // Render without multitexture
- return;
- }
-
LLGLSPipeline gls;
if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
@@ -194,10 +181,6 @@ void LLDrawPoolTerrain::render(S32 pass)
{
renderSimple();
}
- else if (gGLManager.mNumTextureUnits < 4)
- {
- renderFull2TU();
- }
else
{
renderFull4TU();
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index a84f62036e..3f39716449 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -57,6 +57,8 @@ BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
+extern BOOL gCubeSnapshot;
+
LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
{
}
@@ -104,7 +106,7 @@ void LLDrawPoolWater::restoreGL()
void LLDrawPoolWater::prerender()
{
- mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
+ mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
S32 LLDrawPoolWater::getNumPasses()
@@ -117,16 +119,37 @@ S32 LLDrawPoolWater::getNumPasses()
return 0;
}
+S32 LLDrawPoolWater::getNumPostDeferredPasses()
+{
+ return 1;
+}
+
void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
{
- beginRenderPass(pass);
- deferred_render = TRUE;
+ LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
+ if (LLPipeline::sRenderTransparentWater && !gCubeSnapshot)
+ {
+ // copy framebuffer contents so far to a texture to be used for
+ // reflections and refractions
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+ dst.copyContents(src,
+ 0, 0, src.getWidth(), src.getHeight(),
+ 0, 0, dst.getWidth(), dst.getHeight(),
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ GL_NEAREST);
+ }
}
-void LLDrawPoolWater::endPostDeferredPass(S32 pass)
+void LLDrawPoolWater::renderPostDeferred(S32 pass)
{
- endRenderPass(pass);
- deferred_render = FALSE;
+ renderWater();
+}
+
+
+S32 LLDrawPoolWater::getNumDeferredPasses()
+{
+ return 0;
}
//===============================
@@ -134,6 +157,7 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
//===============================
void LLDrawPoolWater::renderDeferred(S32 pass)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
if (!LLPipeline::sRenderTransparentWater)
@@ -146,12 +170,14 @@ void LLDrawPoolWater::renderDeferred(S32 pass)
deferred_render = TRUE;
renderWater();
deferred_render = FALSE;
+#endif
}
//=========================================
void LLDrawPoolWater::render(S32 pass)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
{
@@ -188,12 +214,6 @@ void LLDrawPoolWater::render(S32 pass)
stop_glerror();
- if (!gGLManager.mHasMultitexture)
- {
- // Ack! No multitexture! Bail!
- return;
- }
-
LLFace* refl_face = voskyp->getReflFace();
gPipeline.disableLights();
@@ -243,7 +263,7 @@ void LLDrawPoolWater::render(S32 pass)
glClearStencil(1);
glClear(GL_STENCIL_BUFFER_BIT);
- LLGLEnable gls_stencil(GL_STENCIL_TEST);
+ //LLGLEnable gls_stencil(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
@@ -329,11 +349,13 @@ void LLDrawPoolWater::render(S32 pass)
glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
renderReflection(refl_face);
}
+#endif
}
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOSky *voskyp = gSky.mVOSkyp;
@@ -438,11 +460,13 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+#endif
}
void LLDrawPoolWater::renderReflection(LLFace* face)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOSky *voskyp = gSky.mVOSkyp;
@@ -468,6 +492,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
face->renderIndexed();
+#endif
}
void LLDrawPoolWater::renderWater()
@@ -491,6 +516,8 @@ void LLDrawPoolWater::renderWater()
bool moon_up = environment.getIsMoonUp();
bool has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal");
bool underwater = LLViewerCamera::getInstance()->cameraUnderWater();
+ LLColor4 fog_color = LLColor4(pwater->getWaterFogColor(), 0.f);
+ LLColor3 fog_color_linear = linearColor3(fog_color);
if (sun_up)
{
@@ -526,7 +553,7 @@ void LLDrawPoolWater::renderWater()
for( int edge = 0 ; edge < 2; edge++ )
{
// select shader
- if (underwater && LLPipeline::sWaterReflections)
+ if (underwater)
{
shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
}
@@ -541,7 +568,8 @@ void LLDrawPoolWater::renderWater()
shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram;
}
}
- shader->bind();
+
+ gPipeline.bindDeferredShader(*shader);
// bind textures for water rendering
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
@@ -582,6 +610,8 @@ void LLDrawPoolWater::renderWater()
// bind reflection texture from RenderTarget
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+
F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
@@ -599,7 +629,6 @@ void LLDrawPoolWater::renderWater()
shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
if (screentex > -1)
@@ -608,6 +637,11 @@ void LLDrawPoolWater::renderWater()
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
}
+ if (screenDepth > -1)
+ {
+ gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
+ }
+
if (mShaderLevel == 1)
{
fog_color.mV[VW] = log(fog_density) / log(2);
@@ -621,6 +655,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
@@ -645,7 +680,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
if (LLViewerCamera::getInstance()->cameraUnderWater())
@@ -689,7 +724,8 @@ void LLDrawPoolWater::renderWater()
shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
- shader->unbind();
+ gPipeline.unbindDeferredShader(*shader);
+
gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
}
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 6f2fc3271d..418430d68a 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -35,7 +35,7 @@ class LLHeavenBody;
class LLWaterSurface;
class LLGLSLShader;
-class LLDrawPoolWater: public LLFacePool
+class LLDrawPoolWater final: public LLFacePool
{
protected:
LLPointer<LLViewerTexture> mWaterImagep[2];
@@ -56,26 +56,26 @@ public:
LLVertexBuffer::MAP_TEXCOORD0
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolWater();
/*virtual*/ ~LLDrawPoolWater();
static void restoreGL();
- /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
- /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void renderDeferred(S32 pass = 0);
-
- /*virtual*/ S32 getNumPasses();
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
-
- /*virtual*/ LLViewerTexture *getDebugTexture();
- /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
+
+ S32 getNumPostDeferredPasses() override;
+ void beginPostDeferredPass(S32 pass) override;
+ void renderPostDeferred(S32 pass) override;
+ S32 getNumDeferredPasses() override;
+ void renderDeferred(S32 pass = 0) override;
+
+ S32 getNumPasses() override;
+ void render(S32 pass = 0) override;
+ void prerender() override;
+
+ LLViewerTexture *getDebugTexture() override;
+ LLColor3 getDebugColor() const; // For AGP debug display
void renderReflection(LLFace* face);
void renderWater();
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 9873846669..7157214cbc 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -547,7 +547,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
F32 moon_brightness = (float)psky->getMoonBrightness();
moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness);
- moon_shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
+ moon_shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
//moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
moon_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, psky->getMoonDirection().mV); // shader: moon_dir
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 63e7887d81..361a7666fa 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
}
- if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
+ if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
+ bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
if (use_fbo)
{
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index b76dc6a961..64d89282e2 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1717,8 +1717,19 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
break;
case LLSD::TypeReal:
- shader->uniform1f(it.second.getShaderKey(), value.asReal());
+ {
+ F32 v = value.asReal();
+ switch (it.second.getShaderKey())
+ { // convert to linear color space if this is a color parameter
+ case LLShaderMgr::HAZE_HORIZON:
+ case LLShaderMgr::HAZE_DENSITY:
+ case LLShaderMgr::CLOUD_SHADOW:
+ //v = sRGBtoLinear(v);
+ break;
+ }
+ shader->uniform1f(it.second.getShaderKey(), v);
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ }
break;
case LLSD::TypeBoolean:
@@ -1729,8 +1740,16 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
case LLSD::TypeArray:
{
LLVector4 vect4(value);
+
+ switch (it.second.getShaderKey())
+ { // convert to linear color space if this is a color parameter
+ case LLShaderMgr::BLUE_HORIZON:
+ case LLShaderMgr::BLUE_DENSITY:
+ //vect4 = LLVector4(linearColor4(LLColor4(vect4.mV)).mV);
+ break;
+ }
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
- shader->uniform4fv(it.second.getShaderKey(), vect4 );
+ shader->uniform3fv(it.second.getShaderKey(), LLVector3(vect4.mV) );
break;
}
@@ -2641,7 +2660,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3
if (!water.isUndefined())
{
- environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time));
}
if (updateenvironment)
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 740396178b..23b56aa579 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -64,7 +64,6 @@
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
-extern BOOL gGLDebugLoggingEnabled;
#define LL_MAX_INDICES_COUNT 1000000
static LLStaticHashedString sTextureIndexIn("texture_index_in");
@@ -587,7 +586,6 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
}
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 );
glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -668,7 +666,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
{
LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
- LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+ //LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
if (!wireframe_selection)
{ //modify wireframe into outline selection mode
@@ -1034,12 +1032,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
{
const LLMatrix4& vol_mat = getWorldMatrix();
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
- const LLVector4a& normal4a = vf.mNormals[0];
- const LLVector4a& tangent = vf.mTangents[0];
- if (!&tangent)
+ if (! (vf.mNormals && vf.mTangents))
{
return;
}
+ const LLVector4a& normal4a = *vf.mNormals;
+ const LLVector4a& tangent = *vf.mTangents;
LLVector4a binormal4a;
binormal4a.setCross3(normal4a, tangent);
@@ -1213,55 +1211,6 @@ bool LLFace::canRenderAsMask()
return false;
}
-
-//static
-void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
-
- if (vf.mWeights)
- {
- mask |= LLVertexBuffer::MAP_WEIGHT4;
- }
-
- LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
- vf.mVertexBuffer = buff;
-
- buff->allocateBuffer(vf.mNumVertices, 0, true);
-
- LLStrider<LLVector4a> f_vert;
- LLStrider<LLVector4a> f_tangent;
- LLStrider<LLVector3> f_norm;
- LLStrider<LLVector2> f_tc;
-
- buff->getTangentStrider(f_tangent);
- buff->getVertexStrider(f_vert);
- buff->getNormalStrider(f_norm);
- buff->getTexCoord0Strider(f_tc);
-
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- *f_vert++ = vf.mPositions[i];
- *f_tangent++ = vf.mTangents[i];
- *f_tc++ = vf.mTexCoords[i];
- (*f_norm++).set(vf.mNormals[i].getF32ptr());
- }
-
- if (vf.mWeights)
- {
- LLStrider<LLVector4> f_wght;
- buff->getWeight4Strider(f_wght);
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- (*f_wght++).set(vf.mWeights[i].getF32ptr());
- }
- }
-
- buff->flush();
-}
-
//helper function for pushing primitives for transform shaders and cleaning up
//uninitialized data on the tail, plus tracking number of expected primitives
void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
@@ -1306,7 +1255,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
//don't use map range (generates many redundant unmap calls)
- bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
+ bool map_range = false;
if (mVertexBuffer.notNull())
{
@@ -1385,10 +1334,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U color = tep->getColor();
+ if (tep->getGLTFRenderMaterial())
+ {
+ color = tep->getGLTFRenderMaterial()->mBaseColor;
+ }
+
if (rebuild_color)
{ //decide if shiny goes in alpha channel of color
if (tep &&
- getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
+ !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny
{
LLMaterial* mat = tep->getMaterialParams().get();
@@ -1532,156 +1486,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
-#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
- if (use_transform_feedback &&
- mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- mVertexBuffer->useVBOs() && //target buffer is in VRAM
- !rebuild_weights && //TODO: add support for weights
- !volume.isUnique()) //source volume is NOT flexi
- { //use transform feedback to pack vertex buffer
- //gGLDebugLoggingEnabled = TRUE;
-
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback");
- LLGLEnable discard(GL_RASTERIZER_DISCARD);
- LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
-
- if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
- {
- mVObjp->getVolume()->genTangents(f);
- LLFace::cacheFaceInVRAM(vf);
- buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
- }
-
- LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
-
- gGL.pushMatrix();
- gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
-
- if (rebuild_pos)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position");
- gTransformPositionProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
-
- U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
-
- S32 val = 0;
- U8* vp = (U8*) &val;
- vp[0] = index;
- vp[1] = 0;
- vp[2] = 0;
- vp[3] = 0;
-
- gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
-
- glEndTransformFeedback();
- }
-
- if (rebuild_color)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
-
- S32 val = *((S32*) color.mV);
-
- gTransformColorProgram.uniform1i(sColorIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_emissive)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
-
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
-
- S32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
-
- gTransformColorProgram.uniform1i(sColorIn, glow32);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_normal)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal");
- gTransformNormalProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tangent)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent");
- gTransformTangentProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tcoord)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord");
- gTransformTexCoordProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
-
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
-
- if (do_bump)
- {
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
- }
-
- glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
- gGL.popMatrix();
-
- if (cur_shader)
- {
- cur_shader->bind();
- }
- }
- else
-#endif
{
//if it's not fullbright and has no normals, bake sunlight based on face normal
//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
@@ -1795,10 +1599,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
scalea.load3(scale.mV);
LLMaterial* mat = tep->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- if (mat && !do_bump)
+ if ((mat || gltf_mat) && !do_bump)
{
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
@@ -2024,10 +1829,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->flush();
}
- if (!mat && do_bump)
+ if ((!mat && !gltf_mat) && do_bump)
{
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
+ mVObjp->getVolume()->genTangents(f);
+
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a tangent = vf.mTangents[i];
@@ -2161,20 +1968,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
F32* tangents = (F32*) tangent.get();
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(f);
LLVector4Logical mask;
mask.clear();
mask.setElement<3>();
LLVector4a* src = vf.mTangents;
- LLVector4a* end = vf.mTangents+num_vertices;
+ LLVector4a* end = vf.mTangents +num_vertices;
while (src < end)
{
LLVector4a tangent_out;
mat_normal.rotate(*src, tangent_out);
- tangent_out.normalize3fast();
tangent_out.setSelectWithMask(mask, *src, tangent_out);
tangent_out.store4a(tangents);
@@ -2795,3 +2601,10 @@ U64 LLFace::getSkinHash()
{
return mSkinInfo ? mSkinInfo->mHash : 0;
}
+
+bool LLFace::isInAlphaPool() const
+{
+ return getPoolType() == LLDrawPool::POOL_ALPHA ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_PRE_WATER ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index aa00c9d052..a5ea460061 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -81,8 +81,6 @@ public:
PARTICLE = 0x0080,
};
- static void cacheFaceInVRAM(const LLVolumeFace& vf);
-
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp)
{
@@ -239,6 +237,8 @@ public:
void setDrawOrderIndex(U32 index) { mDrawOrderIndex = index; }
U32 getDrawOrderIndex() const { return mDrawOrderIndex; }
+ // return true if this face is in an alpha draw pool
+ bool isInAlphaPool() const;
public: //aligned members
LLVector4a mExtents[2];
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 1605e4133d..9bb3bac104 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -504,20 +504,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
is.close();
}
- //get time domain
- LLSD::Real cur_total_time = 0.0;
-
- for (U32 i = 0; i < cur_data.size(); ++i)
- {
- cur_total_time += cur_data[i]["Total"]["Time"].asReal();
- }
-
- LLSD::Real base_total_time = 0.0;
- for (U32 i = 0; i < base_data.size(); ++i)
- {
- base_total_time += base_data[i]["Total"]["Time"].asReal();
- }
-
//allocate raw scratch space
LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index c13b63433c..70e8437190 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -471,7 +471,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
}
// check if we are dragging an existing item from the favorites bar
- if (item && mDragItemId == item->getUUID())
+ bool existing_drop = false;
+ if (item && mDragItemId == item->getUUID())
+ {
+ // There is a chance of mDragItemId being obsolete
+ // ex: can happen if something interrupts viewer, which
+ // results in viewer not geting a 'mouse up' signal
+ for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
+ {
+ LLViewerInventoryItem* currItem = *i;
+
+ if (currItem->getUUID() == mDragItemId)
+ {
+ existing_drop = true;
+ break;
+ }
+ }
+ }
+
+ if (existing_drop)
{
*accept = ACCEPT_YES_SINGLE;
@@ -500,6 +518,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (mItems.empty())
{
setLandingTab(NULL);
+ mLastTab = NULL;
}
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
}
@@ -515,6 +534,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
+ if (mItems.empty())
+ {
+ // Isn't supposed to be empty
+ return;
+ }
+
// Identify the button hovered and the side to drop
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
bool insert_before = true;
@@ -772,6 +797,14 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
}
LLFavoritesOrderStorage::instance().mPrevFavorites = mItems;
mGetPrevItems = false;
+
+ if (LLFavoritesOrderStorage::instance().isStorageUpdateNeeded())
+ {
+ if (!mItemsChangedTimer.getStarted())
+ {
+ mItemsChangedTimer.start();
+ }
+ }
}
const LLButton::Params& button_params = getButtonParams();
@@ -779,6 +812,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
if(mItems.empty())
{
mBarLabel->setVisible(TRUE);
+ mLastTab = NULL;
}
else
{
@@ -825,6 +859,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
dynamic_cast<LLFavoriteLandmarkButton*> (*cur_it);
if (button)
{
+ if (mLastTab == button)
+ {
+ mLastTab = NULL;
+ }
removeChild(button);
delete button;
}
@@ -862,6 +900,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
mLastTab = last_new_button;
}
+ if (!mLastTab && mItems.size() > 0)
+ {
+ // mMoreTextBox was removed, so LLFavoriteLandmarkButtons
+ // should be the only ones in the list
+ LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back());
+ if (button)
+ {
+ mLastTab = button;
+ }
+ }
+
mFirstDropDownItem = j;
// Chevron button
if (mFirstDropDownItem < mItems.size())
@@ -1606,7 +1655,7 @@ void LLFavoritesOrderStorage::destroyClass()
file.close();
LLFile::remove(filename);
}
- if(mSaveOnExit)
+ if(mSaveOnExit || gSavedSettings.getBOOL("UpdateRememberPasswordSetting"))
{
LLFavoritesOrderStorage::instance().saveFavoritesRecord(true);
}
@@ -1650,7 +1699,6 @@ void LLFavoritesOrderStorage::load()
llifstream in_file;
in_file.open(filename.c_str());
LLSD fav_llsd;
- LLSD user_llsd;
if (in_file.is_open())
{
LLSDSerialize::fromXML(fav_llsd, in_file);
@@ -1660,12 +1708,12 @@ void LLFavoritesOrderStorage::load()
in_file.close();
if (fav_llsd.isMap() && fav_llsd.has(gAgentUsername))
{
- user_llsd = fav_llsd[gAgentUsername];
+ mStorageFavorites = fav_llsd[gAgentUsername];
S32 index = 0;
bool needs_validation = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
- for (LLSD::array_iterator iter = user_llsd.beginArray();
- iter != user_llsd.endArray(); ++iter)
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
{
// Validation
LLUUID fv_id = iter->get("id").asUUID();
@@ -1967,7 +2015,7 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
}
}
- if((items != mPrevFavorites) || name_changed || pref_changed)
+ if((items != mPrevFavorites) || name_changed || pref_changed || gSavedSettings.getBOOL("UpdateRememberPasswordSetting"))
{
std::string filename = getStoredFavoritesFilename();
if (!filename.empty())
@@ -1988,6 +2036,12 @@ BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
LLSD user_llsd;
S32 fav_iter = 0;
mMissingSLURLs.clear();
+
+ LLSD save_pass;
+ save_pass["save_password"] = gSavedSettings.getBOOL("RememberPassword");
+ user_llsd[fav_iter] = save_pass;
+ fav_iter++;
+
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
{
LLSD value;
@@ -2058,6 +2112,23 @@ void LLFavoritesOrderStorage::showFavoritesOnLoginChanged(BOOL show)
}
}
+bool LLFavoritesOrderStorage::isStorageUpdateNeeded()
+{
+ if (!mRecreateFavoriteStorage)
+ {
+ for (LLSD::array_iterator iter = mStorageFavorites.beginArray();
+ iter != mStorageFavorites.endArray(); ++iter)
+ {
+ if (mFavoriteNames[iter->get("id").asUUID()] != iter->get("name").asString())
+ {
+ mRecreateFavoriteStorage = true;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
{
if (mTargetLandmarkId.isNull()) return;
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2d7ba9df67..3b439b31fd 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -226,8 +226,11 @@ public:
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
- LLInventoryModel::item_array_t mPrevFavorites;
+ bool isStorageUpdateNeeded();
+ LLInventoryModel::item_array_t mPrevFavorites;
+ LLSD mStorageFavorites;
+ bool mRecreateFavoriteStorage;
const static S32 NO_INDEX;
static bool mSaveOnExit;
@@ -254,7 +257,6 @@ private:
slurls_map_t mSLURLs;
std::set<LLUUID> mMissingSLURLs;
bool mIsDirty;
- bool mRecreateFavoriteStorage;
struct IsNotInFavorites
{
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index e934041e2e..5817fdbfa0 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -431,41 +431,9 @@ bool LLFeatureManager::loadGPUClass()
LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
mGPUClass = GPU_CLASS_3;
#else
- if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
- else if (gGLManager.mGLVersion < 3.3f)
- {
- mGPUClass = GPU_CLASS_2;
- }
- else if (gGLManager.mGLVersion < 4.f)
- {
- mGPUClass = GPU_CLASS_3;
- }
- else
- {
- mGPUClass = GPU_CLASS_4;
- }
- if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1)
- {
- // Intels are generally weaker then other GPUs despite having advanced features
- mGPUClass = (EGPUClass)(mGPUClass - 1);
- }
+ mGPUClass = GPU_CLASS_2;
#endif
}
- else if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
else if (gbps <= 5.f)
{
mGPUClass = GPU_CLASS_0;
@@ -607,7 +575,7 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
LLViewerShaderMgr::sSkipReload = true;
-
+ flush_glerror(); // Whatever may have already happened (e.g., to cause us to change), don't let confuse it with new initializations.
applyBaseMasks();
// if we're passed an invalid level, default to "Low"
@@ -679,22 +647,14 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("TexUnit8orLess");
}
- if (gGLManager.mHasMapBufferRange)
- {
- maskFeatures("MapBufferRange");
- }
if (gGLManager.mVRAM > 512)
{
maskFeatures("VRAMGT512");
}
-
-#if LL_DARWIN
- const LLOSInfo& osInfo = LLOSInfo::instance();
- if (osInfo.mMajorVer == 10 && osInfo.mMinorVer < 7)
- {
- maskFeatures("OSX_10_6_8");
- }
-#endif
+ if (gGLManager.mGLVersion < 3.99f)
+ {
+ maskFeatures("GL3");
+ }
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
new file mode 100644
index 0000000000..2d3015635c
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -0,0 +1,103 @@
+/**
+ * @file llfetchedgltfmaterial.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfetchedgltfmaterial.h"
+
+#include "llviewertexturelist.h"
+#include "llavatarappearancedefines.h"
+#include "llshadermgr.h"
+
+LLFetchedGLTFMaterial::LLFetchedGLTFMaterial()
+ : LLGLTFMaterial()
+ , mExpectedFlusTime(0.f)
+ , mActive(true)
+ , mFetching(false)
+{
+
+}
+
+LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
+{
+
+}
+
+void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader)
+{
+ // glTF 2.0 Specification 3.9.4. Alpha Coverage
+ // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
+ F32 min_alpha = -1.0;
+
+ if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ min_alpha = mAlphaCutoff;
+ }
+ shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
+
+ if (mBaseColorTexture.notNull())
+ {
+ gGL.getTexUnit(0)->bindFast(mBaseColorTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+
+ if (mNormalTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture);
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+
+ if (mMetallicRoughnessTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, mMetallicRoughnessTexture); // PBR linear packed Occlusion, Roughness, Metal.
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ if (mEmissiveTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, mEmissiveTexture); // PBR sRGB Emissive
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ // NOTE: base color factor is baked into vertex stream
+
+ shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor);
+ shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
+ shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
+
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
new file mode 100644
index 0000000000..3b2801bf77
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -0,0 +1,57 @@
+/**
+ * @file llfetchedgltfmaterial.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+#include "llviewertexture.h"
+
+class LLGLSLShader;
+
+class LLFetchedGLTFMaterial: public LLGLTFMaterial
+{
+ friend class LLGLTFMaterialList; // for lifetime management
+public:
+ LLFetchedGLTFMaterial();
+ virtual ~LLFetchedGLTFMaterial();
+
+ // bind this material for rendering
+ void bind(LLGLSLShader* shader);
+
+ // Textures used for fetching/rendering
+ LLPointer<LLViewerFetchedTexture> mBaseColorTexture;
+ LLPointer<LLViewerFetchedTexture> mNormalTexture;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
+ LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
+
+protected:
+ //Lifetime management
+ F64 mExpectedFlusTime; // since epoch in seconds
+ bool mActive;
+ bool mFetching;
+};
+
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 3669fb1eeb..1dd9a43b72 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -55,13 +55,13 @@ LLFilePicker LLFilePicker::sInstance;
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0"
#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0"
-#ifdef _CORY_TESTING
-#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0"
-#endif
+#define GLTF_FILTER L"glTF (*.gltf; *.glb)\0*.gltf;*.glb\0"
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
+#define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
#endif
@@ -193,16 +193,14 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = ANIM_FILTER \
L"\0";
break;
- case FFLOAD_COLLADA:
+ case FFLOAD_GLTF:
+ mOFN.lpstrFilter = GLTF_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_COLLADA:
mOFN.lpstrFilter = COLLADA_FILTER \
L"\0";
break;
-#ifdef _CORY_TESTING
- case FFLOAD_GEOMETRY:
- mOFN.lpstrFilter = GEOMETRY_FILTER \
- L"\0";
- break;
-#endif
case FFLOAD_XML:
mOFN.lpstrFilter = XML_FILTER \
L"\0";
@@ -219,6 +217,16 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = MODEL_FILTER \
L"\0";
break;
+ case FFLOAD_MATERIAL:
+ mOFN.lpstrFilter = MATERIAL_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_MATERIAL_TEXTURE:
+ mOFN.lpstrFilter = MATERIAL_TEXTURES_FILTER \
+ MATERIAL_FILTER \
+ IMAGE_FILTER \
+ L"\0";
+ break;
case FFLOAD_SCRIPT:
mOFN.lpstrFilter = SCRIPT_FILTER \
L"\0";
@@ -480,18 +488,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
L"XAF Anim File (*.xaf)\0*.xaf\0" \
L"\0";
break;
-#ifdef _CORY_TESTING
- case FFSAVE_GEOMETRY:
+ case FFSAVE_GLTF:
if (filename.empty())
{
- wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
}
- mOFN.lpstrDefExt = L"slg";
+ mOFN.lpstrDefExt = L"glb";
mOFN.lpstrFilter =
- L"SLG SL Geometry File (*.slg)\0*.slg\0" \
+ L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \
L"\0";
break;
-#endif
case FFSAVE_XML:
if (filename.empty())
{
@@ -621,14 +627,13 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //
allowedv->push_back("bvh");
allowedv->push_back("anim");
break;
+ case FFLOAD_GLTF:
+ allowedv->push_back("gltf");
+ allowedv->push_back("glb");
+ break;
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
-#ifdef _CORY_TESTING
- case FFLOAD_GEOMETRY:
- allowedv->push_back("slg");
- break;
-#endif
case FFLOAD_XML:
allowedv->push_back("xml");
break;
@@ -728,13 +733,11 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
extension = "xaf";
break;
-#ifdef _CORY_TESTING
- case FFSAVE_GEOMETRY:
+ case FFSAVE_GLTF:
type = "\?\?\?\?";
creator = "\?\?\?\?";
- extension = "slg";
+ extension = "glb";
break;
-#endif
case FFSAVE_XML:
type = "\?\?\?\?";
@@ -1354,10 +1357,13 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
case FFLOAD_XML:
filtername = add_xml_filter_to_gtkchooser(picker);
break;
- case FFLOAD_COLLADA:
- filtername = add_collada_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_IMAGE:
+ case FFLOAD_GLTF:
+ filtername = dead_code_should_blow_up_here(picker);
+ break;
+ case FFLOAD_COLLADA:
+ filtername = add_collada_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_IMAGE:
filtername = add_imageload_filter_to_gtkchooser(picker);
break;
case FFLOAD_SCRIPT:
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 04ba4416d7..a03f3f6711 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -77,9 +77,7 @@ public:
FFLOAD_WAV = 2,
FFLOAD_IMAGE = 3,
FFLOAD_ANIM = 4,
-#ifdef _CORY_TESTING
- FFLOAD_GEOMETRY = 5,
-#endif
+ FFLOAD_GLTF = 5,
FFLOAD_XML = 6,
FFLOAD_SLOBJECT = 7,
FFLOAD_RAW = 8,
@@ -88,7 +86,9 @@ public:
FFLOAD_SCRIPT = 11,
FFLOAD_DICTIONARY = 12,
FFLOAD_DIRECTORY = 13, // To call from lldirpicker.
- FFLOAD_EXE = 14 // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_MATERIAL = 15,
+ FFLOAD_MATERIAL_TEXTURE = 16,
};
enum ESaveFilter
@@ -99,9 +99,7 @@ public:
FFSAVE_BMP = 5,
FFSAVE_AVI = 6,
FFSAVE_ANIM = 7,
-#ifdef _CORY_TESTING
- FFSAVE_GEOMETRY = 8,
-#endif
+ FFSAVE_GLTF = 8,
FFSAVE_XML = 9,
FFSAVE_COLLADA = 10,
FFSAVE_RAW = 11,
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 4f3c2d8d34..d5115df35f 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -386,7 +386,8 @@ void LLVolumeImplFlexible::doIdleUpdate()
U64 throttling_delay = (virtual_frame_num + id) % update_period;
if ((throttling_delay == 0 && mLastFrameNum < virtual_frame_num) //one or more virtual frames per frame
- || (mLastFrameNum + update_period < virtual_frame_num)) // missed virtual frame
+ || (mLastFrameNum + update_period < virtual_frame_num) // missed virtual frame
+ || mLastFrameNum > virtual_frame_num) // overflow
{
// We need mLastFrameNum to compensate for 'unreliable time' and to filter 'duplicate' frames
// If happened too late, subtract throttling_delay (it is zero otherwise)
@@ -787,10 +788,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
volume->updateRelativeXform();
- if (mRenderRes > -1)
- {
- doFlexibleUpdate();
- }
+ doFlexibleUpdate();
// Object may have been rotated, which means it needs a rebuild. See SL-47220
BOOL rotated = FALSE;
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index ffbb0bbee9..c075f7e8bd 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
+ return true;
+}
+
+void LLFloater360Capture::onOpen(const LLSD& key)
+{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
-
- return true;
}
// called when the user choose a quality level using
diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h
index 6da7ee074a..8f765c0b1b 100644
--- a/indra/newview/llfloater360capture.h
+++ b/indra/newview/llfloater360capture.h
@@ -47,6 +47,7 @@ class LLFloater360Capture:
~LLFloater360Capture();
BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
void changeInterestListMode(bool send_everything);
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index ec05ba924c..0964daa4d5 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -350,7 +350,7 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry()
// called when the Import List button is pressed
void LLFloaterAutoReplaceSettings::onImportList()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames)
@@ -537,7 +537,7 @@ void LLFloaterAutoReplaceSettings::onExportList()
{
std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
std::string listFileName = listName + ".xml";
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName);
}
void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName)
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index ab95bc06b8..0186c4aebe 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
+ mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; i<avatar_ids.size(); i++)
{
LLUUID& av = avatar_ids[i];
- if(av == gAgent.getID()) continue;
+ if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;
LLSD element;
element["id"] = av; // value
LLAvatarName av_name;
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index a1a06706bc..a3cc939f85 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -306,6 +306,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) ||
( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) ||
( asstype == LLAssetType::AT_SETTINGS && gSavedSettings.getBOOL("BulkChangeIncludeSettings" )) ||
+ ( asstype == LLAssetType::AT_MATERIAL && gSavedSettings.getBOOL("BulkChangeIncludeMaterials")) ||
( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" )))
{
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index a3037ed651..ed3dc37043 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()
loaderp->serialize(dp);
dp.reset();
LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
- BOOL success = motionp && motionp->deserialize(dp, mMotionID);
+ BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);
LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;
@@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
mDummyAvatar->mSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideSkirt();
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index 45aea00a49..67c412dfa6 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
new file mode 100644
index 0000000000..3520b0f67a
--- /dev/null
+++ b/indra/newview/llfloaterclassified.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llfloaterclassified.cpp
+ * @brief LLFloaterClassified for displaying classifieds.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterclassified.h"
+
+LLFloaterClassified::LLFloaterClassified(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterClassified::~LLFloaterClassified()
+{
+}
+
+void LLFloaterClassified::onOpen(const LLSD& key)
+{
+ LLPanel* panel = findChild<LLPanel>("main_panel", true);
+ if (panel)
+ {
+ panel->onOpen(key);
+ }
+ if (key.has("classified_name"))
+ {
+ setTitle(key["classified_name"].asString());
+ }
+ LLFloater::onOpen(key);
+}
+
+BOOL LLFloaterClassified::postBuild()
+{
+ return TRUE;
+}
+
+
+bool LLFloaterClassified::matchesKey(const LLSD& key)
+{
+ bool is_mkey_valid = mKey.has("classified_id");
+ bool is_key_valid = key.has("classified_id");
+ if (is_mkey_valid && is_key_valid)
+ {
+ return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
+ }
+ return is_mkey_valid == is_key_valid;
+}
+
+// eof
diff --git a/indra/newview/llpanelme.h b/indra/newview/llfloaterclassified.h
index 60e9d4317d..2c95d82b2c 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llfloaterclassified.h
@@ -1,50 +1,45 @@
-/**
- * @file llpanelme.h
- * @brief Side tray "Me" (My Profile) panel
+/**
+ * @file llfloaterclassified.h
+ * @brief LLFloaterClassified for displaying classifieds.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LL_LLPANELMEPROFILE_H
-#define LL_LLPANELMEPROFILE_H
+#ifndef LL_LLFLOATERCLASSIFIED_H
+#define LL_LLFLOATERCLASSIFIED_H
-#include "llpanel.h"
-#include "llpanelprofile.h"
+#include "llfloater.h"
-/**
-* Panel for displaying Agent's Picks and Classifieds panel.
-* LLPanelMe allows user to edit his picks and classifieds.
-*/
-class LLPanelMe : public LLPanelProfile
+class LLFloaterClassified : public LLFloater
{
- LOG_CLASS(LLPanelMe);
-
+ LOG_CLASS(LLFloaterClassified);
public:
+ LLFloaterClassified(const LLSD& key);
+ virtual ~LLFloaterClassified();
- LLPanelMe();
-
- /*virtual*/ void onOpen(const LLSD& key);
+ void onOpen(const LLSD& key) override;
+ BOOL postBuild() override;
- /*virtual*/ BOOL postBuild();
+ bool matchesKey(const LLSD& key) override;
};
-#endif // LL_LLPANELMEPROFILE_H
+#endif // LL_LLFLOATERCLASSIFIED_H
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 1a784223c2..ba91277c79 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -173,7 +173,6 @@ void LLFloaterColorPicker::showUI ()
openFloater(getKey());
setVisible ( TRUE );
setFocus ( TRUE );
- setRevertOnCancel(FALSE);
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -185,15 +184,23 @@ void LLFloaterColorPicker::showUI ()
// code that will get switched in for default system color picker
if ( swatch )
{
+ // Todo: this needs to be threaded for viewer not to timeout
LLColor4 curCol = swatch->get ();
send_agent_pause();
- getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
+ bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
send_agent_resume();
- setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
- setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
-
- LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
+ if (commit)
+ {
+ setOrigRgb(curCol[0], curCol[1], curCol[2]);
+ setCurRgb(curCol[0], curCol[1], curCol[2]);
+
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT);
+ }
+ else
+ {
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL);
+ }
}
closeFloater();
@@ -391,10 +398,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data )
if ( self )
{
- if(self->getRevertOnCancel())
- {
- self->cancelSelection ();
- }
+ self->cancelSelection();
self->closeFloater();
}
}
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 16974a872e..39dbc5b763 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -104,9 +104,6 @@ class LLFloaterColorPicker
void setMouseDownInSwatch (BOOL mouse_down_in_swatch);
BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; }
- void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; };
- BOOL getRevertOnCancel () { return mRevertOnCancel; }
-
BOOL isColorChanged ();
// called when text entries (RGB/HSL etc.) are changed by user
@@ -149,8 +146,6 @@ class LLFloaterColorPicker
BOOL mMouseDownInHueRegion;
BOOL mMouseDownInSwatch;
- BOOL mRevertOnCancel;
-
const S32 mRGBViewerImageLeft;
const S32 mRGBViewerImageTop;
const S32 mRGBViewerImageWidth;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 6b1d9306fb..7def855d83 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -46,19 +46,60 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
-class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+class LLLandmarksInventoryObserver : public LLInventoryObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
+ void changed(U32 mask) override
+ {
+ if (mFloater->getItem())
+ {
+ checkChanged(mask);
+ }
+ else
+ {
+ checkCreated(mask);
+ }
+ }
+
protected:
- /*virtual*/ void done()
+ void checkCreated(U32 mask)
{
+ if (gInventory.getAddedIDs().empty())
+ {
+ return;
+ }
+
+ if (!(mask & LLInventoryObserver::ADD) ||
+ !(mask & LLInventoryObserver::CREATE) ||
+ !(mask & LLInventoryObserver::UPDATE_CREATE))
+ {
+ return;
+ }
+
mFloater->setItem(gInventory.getAddedIDs());
}
+ void checkChanged(U32 mask)
+ {
+ if (gInventory.getChangedIDs().empty())
+ {
+ return;
+ }
+
+ if ((mask & LLInventoryObserver::LABEL) ||
+ (mask & LLInventoryObserver::INTERNAL) ||
+ (mask & LLInventoryObserver::REMOVE) ||
+ (mask & LLInventoryObserver::STRUCTURE) ||
+ (mask & LLInventoryObserver::REBUILD))
+ {
+ mFloater->updateItem(gInventory.getChangedIDs(), mask);
+ }
+ }
+
private:
LLFloaterCreateLandmark* mFloater;
};
@@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild()
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+ mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+ mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
@@ -204,6 +248,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
}
}
+void LLFloaterCreateLandmark::onCommitTextChanges()
+{
+ if (mItem.isNull())
+ {
+ return;
+ }
+ std::string current_title_value = mLandmarkTitleEditor->getText();
+ std::string item_title_value = mItem->getName();
+ std::string current_notes_value = mNotesEditor->getText();
+ std::string item_notes_value = mItem->getDescription();
+
+ LLStringUtil::trim(current_title_value);
+ LLStringUtil::trim(current_notes_value);
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ LLPointer<LLInventoryCallback> cb;
+ LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+ gInventory.accountForUpdate(up);
+ update_inventory_item(new_item, cb);
+ }
+}
+
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
@@ -278,6 +349,8 @@ void LLFloaterCreateLandmark::onSaveClicked()
new_item->updateParentOnServer(FALSE);
}
+ removeObserver();
+
gInventory.updateItem(new_item);
gInventory.notifyObservers();
@@ -286,6 +359,7 @@ void LLFloaterCreateLandmark::onSaveClicked()
void LLFloaterCreateLandmark::onCancelClicked()
{
+ removeObserver();
if (!mItem.isNull())
{
LLUUID item_id = mItem->getUUID();
@@ -314,10 +388,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
if(!getItem())
{
- removeObserver();
mItem = item;
+ mAssetID = mItem->getAssetUUID();
+ setVisibleAndFrontmost(true);
break;
}
}
}
}
+
+void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
+{
+ if (!getItem())
+ {
+ return;
+ }
+
+ LLUUID landmark_id = getItem()->getUUID();
+
+ for (uuid_set_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLUUID& item_id = (*item_iter);
+ if (landmark_id == item_id)
+ {
+ if (getItem() != gInventory.getItem(item_id))
+ {
+ // item is obsolete or removed
+ closeFloater();
+ }
+
+ LLUUID folder_id = mFolderCombo->getValue().asUUID();
+ if (folder_id != mItem->getParentUUID())
+ {
+ // user moved landmark in inventory,
+ // assume that we are done all other changes should already be commited
+ closeFloater();
+ }
+
+ if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID())
+ {
+ closeFloater();
+ }
+
+ if (mask & LLInventoryObserver::LABEL)
+ {
+ mLandmarkTitleEditor->setText(mItem->getName());
+ }
+
+ if (mask & LLInventoryObserver::INTERNAL)
+ {
+ mNotesEditor->setText(mItem->getDescription());
+ }
+ }
+ }
+}
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
index 74ac5e651c..d84f5ae1fc 100644
--- a/indra/newview/llfloatercreatelandmark.h
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -49,6 +49,7 @@ public:
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
+ void updateItem(const uuid_set_t& items, U32 mask);
LLInventoryItem* getItem() { return mItem; }
@@ -56,6 +57,7 @@ private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+ void onCommitTextChanges();
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
@@ -66,6 +68,7 @@ private:
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
+ LLUUID mAssetID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000000..3b0c67415a
--- /dev/null
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llfloaterdisplayname.cpp
+ * @author Leyla Farazha
+ * @brief Implementation of the LLFloaterDisplayName class.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llnotificationsutil.h"
+#include "llviewerdisplayname.h"
+
+#include "llnotifications.h"
+#include "llfloaterdisplayname.h"
+#include "llavatarnamecache.h"
+
+#include "llagent.h"
+
+
+class LLFloaterDisplayName : public LLFloater
+{
+public:
+ LLFloaterDisplayName(const LLSD& key);
+ virtual ~LLFloaterDisplayName() { }
+ /*virtual*/ BOOL postBuild();
+ void onSave();
+ void onCancel();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+
+ void onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content);
+};
+
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
+{
+}
+
+void LLFloaterDisplayName::onOpen(const LLSD& key)
+{
+ getChild<LLUICtrl>("display_name_editor")->clear();
+ getChild<LLUICtrl>("display_name_confirm")->clear();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // ...can't update until some time in the future
+ F64 next_update_local_secs =
+ av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
+ LLDate next_update_local(next_update_local_secs);
+ // display as "July 18 12:17 PM"
+ std::string next_update_string =
+ next_update_local.toHTTPDateString("%B %d %I:%M %p");
+ getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
+ getChild<LLUICtrl>("lockout_text")->setVisible(true);
+ getChild<LLUICtrl>("save_btn")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
+ getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
+
+ }
+ else
+ {
+ getChild<LLUICtrl>("lockout_text")->setVisible(false);
+ getChild<LLUICtrl>("save_btn")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
+
+ }
+}
+
+BOOL LLFloaterDisplayName::postBuild()
+{
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
+ getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
+
+ center();
+
+ return TRUE;
+}
+
+void LLFloaterDisplayName::onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content)
+{
+ if (success)
+ {
+ // Inform the user that the change took place, but will take a while
+ // to percolate.
+ LLSD args;
+ args["DISPLAY_NAME"] = content["display_name"];
+ LLNotificationsUtil::add("SetDisplayNameSuccess", args);
+ return;
+ }
+
+ // Request failed, notify the user
+ std::string error_tag = content["error_tag"].asString();
+ LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
+
+ // We might have a localized string for this message
+ // error_args will usually be empty from the server.
+ if (!error_tag.empty()
+ && LLNotifications::getInstance()->templateExists(error_tag))
+ {
+ LLNotificationsUtil::add(error_tag);
+ return;
+ }
+
+ // The server error might have a localized message for us
+ std::string lang_code = LLUI::getLanguage();
+ LLSD error_desc = content["error_description"];
+ if (error_desc.has( lang_code ))
+ {
+ LLSD args;
+ args["MESSAGE"] = error_desc[lang_code].asString();
+ LLNotificationsUtil::add("GenericAlert", args);
+ return;
+ }
+
+ // No specific error, throw a generic one
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+}
+
+void LLFloaterDisplayName::onCancel()
+{
+ setVisible(false);
+}
+
+void LLFloaterDisplayName::onSave()
+{
+ std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
+ std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
+
+ if (display_name_utf8.compare(display_name_confirm))
+ {
+ LLNotificationsUtil::add("SetDisplayNameMismatch");
+ return;
+ }
+
+ const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
+ LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
+ if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
+ {
+ LLSD args;
+ args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
+ LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
+ return;
+ }
+
+ if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
+ {
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ }
+
+ setVisible(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterDisplayNameUtil::registerFloater()
+{
+ LLFloaterReg::add("display_name", "floater_display_name.xml",
+ &LLFloaterReg::build<LLFloaterDisplayName>);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/llfloaterdisplayname.h
index ca9ce3a2e1..a00bf56712 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
+++ b/indra/newview/llfloaterdisplayname.h
@@ -1,9 +1,9 @@
/**
- * @file pointShadowBlur.glsl
+ * @file llfloaterdisplayname.h
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * 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
@@ -23,15 +23,16 @@
* $/LicenseInfo$
*/
-uniform samplerCube cube_map;
+#ifndef LLFLOATERDISPLAYNAME_H
+#define LLFLOATERDISPLAYNAME_H
-in vec3 to_vec;
-out vec4 fragColor;
-
-void main()
+namespace LLFloaterDisplayNameUtil
{
- vec4 vcol = texture(cube_map, to_vec);
- fragColor = vec4(vcol.rgb, 1.0);
+ // Register with LLFloaterReg
+ void registerFloater();
}
+
+
+#endif
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 24673d5a7c..6e8143384a 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(dayclone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
@@ -1523,7 +1524,7 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
void LLFloaterEditExtDayCycle::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index a6640cc073..a3504ac6ee 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -108,11 +108,12 @@ void LLFloaterEvent::setEventID(const U32 event_id)
LLSD subs;
subs["EVENT_ID"] = (S32)event_id;
// get the search URL and expand all of the substitutions
- // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
- std::ostringstream url;
- url << gSavedSettings.getString("EventURL") << event_id << std::endl;
+ // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)
+
+ std::string expanded_url = LLWeb::expandURLSubstitutions(gSavedSettings.getString("EventURL"), subs);
+
// and load the URL in the web view
- mBrowser->navigateTo(url.str());
+ mBrowser->navigateTo(expanded_url);
}
}
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index fec218ca3b..b9dc14ac1a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(setting_clone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
@@ -439,7 +440,7 @@ void LLFloaterFixedEnvironmentWater::onOpen(const LLSD& key)
void LLFloaterFixedEnvironmentWater::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<std::string>& filenames)
@@ -525,7 +526,7 @@ void LLFloaterFixedEnvironmentSky::onClose(bool app_quitting)
void LLFloaterFixedEnvironmentSky::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6e326ff3cf..d17889bed1 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
- mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 42c5e40761..a00fc4aa84 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 value = sldrCtrl->getValueF32();
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, false);
+ if (isAgentAvatarValid())
+ {
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ F32 value = sldrCtrl->getValueF32();
+ LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
}
// Do send-to-the-server work when slider drag completes, or new
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1525bb9952..703b5d0011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
+#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
+ else if ("report_abuse" == command)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(userID, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(userID, "not avaliable");
+ }
+ }
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
- if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ if (("can_invite" == item)
+ || ("can_chat_history" == item)
+ || ("can_share" == item)
+ || ("can_pay" == item)
+ || ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 3a850d4b68..4cceddeefb 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -698,7 +698,6 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha
void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
{
- LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
@@ -858,6 +857,12 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
{
+ LL_DEBUGS("UIUsage") << "Nearby chat, text " << utf8_out_text << " type " << type << " channel " << channel << LL_ENDL;
+ if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) // prune back some redundant logging
+ {
+ LLUIUsage::instance().logCommand("Chat.SendNearby"); // pseuo-command
+ }
+
LLMessageSystem* msg = gMessageSystem;
if (channel >= 0)
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 34499ac170..93a0b39e02 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -551,7 +551,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
{
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
- if (widget)
+ if (widget && widget->getViewModelItem())
{
widget->refresh();
}
@@ -576,8 +576,11 @@ void LLFloaterIMSessionTab::refreshConversation()
{
participants_uuids.push_back(widget_it->first);
}
- widget_it->second->refresh();
- widget_it->second->setVisible(TRUE);
+ if (widget_it->second->getViewModelItem())
+ {
+ widget_it->second->refresh();
+ widget_it->second->setVisible(TRUE);
+ }
++widget_it;
}
if (is_ad_hoc || mIsP2PChat)
@@ -1126,7 +1129,10 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
for (; it != it_end; ++it)
{
LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
- selected_uuids.push_back(conversation_item->getUUID());
+ if (conversation_item)
+ {
+ selected_uuids.push_back(conversation_item->getUUID());
+ }
}
}
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 93a26f31cc..558b14bba7 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -292,7 +292,7 @@ void LLFloaterJoystick::refreshListOfDevices()
std::string desc = LLViewerJoystick::getInstance()->getDescription();
if (!desc.empty())
{
- LLSD value = LLSD::Integer(0);
+ LLSD value = LLSD::Integer(1); // value for selection
addDevice(desc, value);
mHasDeviceList = true;
}
@@ -392,6 +392,9 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
LLSD value = self->mJoysticksCombo->getValue();
bool joystick_enabled = true;
+ // value is 0 for no device,
+ // 1 for a device on Mac (single device, no list support yet)
+ // binary packed guid for a device on windows (can have multiple devices)
if (value.isInteger())
{
// ndof already has a device selected, we are just setting it enabled or disabled
@@ -400,7 +403,7 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
else
{
LLViewerJoystick::getInstance()->initDevice(value);
- // else joystick is enabled, because combobox holds id of device
+ // else joystick is enabled, because combobox holds id of the device
joystick_enabled = true;
}
gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 04133f2710..1a98ab9d76 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -452,7 +452,8 @@ BOOL LLPanelLandGeneral::postBuild()
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
- mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setCommitCallback(onCommitAny, this);
+ mEditDesc->setContentTrusted(false);
// No prevalidate function - historically the prevalidate function was broken,
// allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
// preserve that ability.
@@ -749,6 +750,7 @@ void LLPanelLandGeneral::refresh()
BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY);
mEditName->setEnabled(can_edit_identity);
mEditDesc->setEnabled(can_edit_identity);
+ mEditDesc->setParseURLs(!can_edit_identity);
BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS);
mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned());
@@ -3054,7 +3056,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
-
+ mTextEstateOwner = getChild<LLTextBox>("estate_owner_text");
+ mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);
return TRUE;
}
@@ -3162,8 +3165,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
if (self)
{
- LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text");
- if (editor) editor->setText(name);
+ self->mTextEstateOwner->setText(name);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 5d9b411f04..684950d88b 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -413,6 +413,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
+ LLTextBox* mTextEstateOwner;
};
#endif
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index fc2da772f3..fd1af7ccc0 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
+const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
//
// Member functions
@@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
- mMap = getChild<LLNetMap>("Net Map");
- if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- mMap->setToolTipMsg(getString("AltToolTipMsg"));
- }
- else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
- {
- mMap->setToolTipMsg(getString("ToolTipMsg"));
- }
- sendChildToBack(mMap);
-
- mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
- mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
- mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
- mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
- mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
- mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
- mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
- mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
-
- updateMinorDirections();
-
- // Get the drag handle all the way in back
- sendChildToBack(getDragHandle());
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- return TRUE;
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ mMap->setParcelNameMsg(getString("ParcelNameMsg"));
+ mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg"));
+ mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg"));
+ mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg"));
+ mMap->setRegionNameMsg(getString("RegionNameMsg"));
+ mMap->setToolTipHintMsg(getString("ToolTipHintMsg"));
+ mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox>("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox>("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest");
+
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast->reshapeToFitText();
+ mTextBoxNorthEast->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest->reshapeToFitText();
+
+ updateMinorDirections();
+
+ // Get the drag handle all the way in back
+ sendChildToBack(getDragHandle());
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, false);
+
+ return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
+void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)
{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2;
- F32 map_half_width = (F32)(getRect().getWidth() / 2) ;
- F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
- F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
- F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(
- ll_round(map_half_width - text_half_width + radius * cos( rotation )),
- ll_round(map_half_height - text_half_height + radius * sin( rotation )) );
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
+
+ F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2);
+ F32 map_half_width = (F32) (getRect().getWidth() / 2);
+ F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2);
+ F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2);
+ F32 pos_half_height = map_half_height - text_half_height - extra_padding;
+ F32 pos_half_width = map_half_width - text_half_width - extra_padding;
+
+ F32 corner_angle = atan2(pos_half_height, pos_half_width);
+ F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI));
+ if (rotation < 0)
+ {
+ rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top;
+ }
+ F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO));
+ bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle;
+
+ F32 part_x = cos(rotation);
+ F32 part_y = sin(rotation);
+ F32 y;
+ F32 x;
+ if (at_left_right_edge)
+ {
+ x = std::copysign(pos_half_width, part_x);
+ y = x * part_y / part_x;
+ }
+ else
+ {
+ y = std::copysign(pos_half_height, part_y);
+ x = y * part_x / part_y;
+ }
+
+ text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));
}
void LLFloaterMap::updateMinorDirections()
@@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
-void LLFloaterMap::handleZoom(const LLSD& userdata)
-{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- mMap->setScale(scale);
- }
-}
-
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ff2fb20535..929b1795aa 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -48,7 +48,6 @@ public:
/*virtual*/ void draw();
private:
- void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 524162ba51..e755e9924c 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
- if (mRootFolderId.notNull())
+ if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
+ {
+ std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
+ if (reason.empty())
+ {
+ text = LLTrans::getString("InventoryMarketplaceConnectionError");
+ }
+ else
+ {
+ LLSD args;
+ args["[REASON]"] = reason;
+ text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
+ }
+
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
+ }
+ else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2afd889609..b34961e8a2 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -157,6 +157,18 @@ void LLFloaterMediaSettings::apply()
}
////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onOpen(const LLSD& key)
+{
+ if (mPanelMediaSettingsGeneral)
+ {
+ // media is expensive, so only load it when nessesary.
+ // If we need to preload it, set volume to 0 and any pause
+ // if applicable, then unpause here
+ mPanelMediaSettingsGeneral->updateMediaPreview();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose(bool app_quitting)
{
if(mPanelMediaSettingsGeneral)
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index f93512eb3a..151e43e6b9 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index fe5120376c..cba074b380 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -97,7 +97,7 @@ private:
};
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
-: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
+: LLFilePickerThread(LLFilePicker::FFLOAD_MODEL)
{
mMP = mp;
mLOD = lod;
@@ -330,8 +330,8 @@ void LLFloaterModelPreview::initModelPreview()
S32 tex_width = 512;
S32 tex_height = 512;
- S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenWidth);
- S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenHeight);
+ S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->width);
+ S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->height);
while ((tex_width << 1) < max_width)
{
@@ -467,22 +467,25 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
mModelPreview->mLoading = true;
if (lod == LLModel::LOD_PHYSICS)
{
// loading physics from file
mModelPreview->mPhysicsSearchLOD = lod;
+ mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;
}
-
+}
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ prepareToLoadModel(lod);
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
{
- mModelPreview->mLoading = true;
-
+ prepareToLoadModel(lod);
mModelPreview->loadModel(file_name, lod, force_disable_slm);
}
@@ -507,6 +510,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
+
+ //disable "simplification" UI
+ LLPanel* simplification_panel = getChild<LLPanel>("physics simplification");
+ LLView* child = simplification_panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(false);
+ child = simplification_panel->findNextSibling(child);
+ }
}
// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function
@@ -741,7 +753,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
case LLModelPreview::MESH_OPTIMIZER_AUTO:
case LLModelPreview::MESH_OPTIMIZER_SLOPPY:
- case LLModelPreview::MESH_OPTIMIZER_COMBINE:
+ case LLModelPreview::MESH_OPTIMIZER_PRECISE:
mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, mode);
break;
default:
@@ -1063,11 +1075,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
}
S32 file_mode = iface->getItemCount() - 1;
- if (which_mode < file_mode)
+ S32 cube_mode = file_mode - 1;
+ if (which_mode < cube_mode)
{
S32 which_lod = num_lods - which_mode;
sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
}
+ else if (which_mode == cube_mode)
+ {
+ std::string path = gDirUtilp->getAppRODataDir();
+ gDirUtilp->append(path, "cube.dae");
+ sInstance->loadModel(LLModel::LOD_PHYSICS, path);
+ }
LLModelPreview *model_preview = sInstance->mModelPreview;
if (model_preview)
@@ -1662,15 +1681,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
if (lod == LLModel::LOD_PHYSICS)
- {
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
- lod_combo->setCurrentByIndex(5);
+ lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
-{
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{
@@ -1745,7 +1764,7 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
S32 index = lod_source_combo->getCurrentIndex();
if (index == LLModelPreview::MESH_OPTIMIZER_AUTO
|| index == LLModelPreview::MESH_OPTIMIZER_SLOPPY
- || index == LLModelPreview::MESH_OPTIMIZER_COMBINE)
+ || index == LLModelPreview::MESH_OPTIMIZER_PRECISE)
{ //rebuild LoD to update triangle counts
onLODParamCommit(lod, true);
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 1e147cd555..bda042186b 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -221,6 +221,7 @@ private:
void resetUploadOptions();
void clearLogTab();
+ void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index dccef88e41..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 87973c2286..94261b2e4e 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
-typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 649a107d74..fb55c6c6c4 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -123,6 +123,7 @@ const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
"Gestures",
"Wearables",
"Settings"
+ "Materials"
};
BOOL LLFloaterPermsDefault::postBuild()
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 70114df989..b3403fda0f 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -333,60 +333,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
- storeAvatarProperties( pAvatarData );
- processProfileProperties( pAvatarData );
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
}
}
}
-void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
+void LLFloaterPreference::saveAvatarProperties( void )
{
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- mAvatarProperties.avatar_id = pAvatarData->avatar_id;
- mAvatarProperties.image_id = pAvatarData->image_id;
- mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
- mAvatarProperties.about_text = pAvatarData->about_text;
- mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
- mAvatarProperties.profile_url = pAvatarData->profile_url;
- mAvatarProperties.flags = pAvatarData->flags;
- mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
+ const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
- mAvatarDataInitialized = true;
- }
-}
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
-void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
-{
- getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
}
-void LLFloaterPreference::saveAvatarProperties( void )
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
{
- const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
- if (allowPublish)
- {
- mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
- }
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
- //
- // NOTE: We really don't want to send the avatar properties unless we absolutely
- // need to so we can avoid the accidental profile reset bug, so, if we're
- // logged in, the avatar data has been initialized and we have a state change
- // for the "allow publish" flag, then set the flag to its new value and send
- // the properties update.
- //
- // NOTE: The only reason we can not remove this update altogether is because of the
- // "allow publish" flag, the last remaining profile setting in the viewer
- // that doesn't exist in the web profile.
- //
- if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
- {
- mAvatarProperties.allow_publish = allowPublish;
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
- }
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@@ -400,6 +399,7 @@ BOOL LLFloaterPreference::postBuild()
gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this));
+ gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this));
gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this));
gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this));
gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this));
@@ -689,6 +689,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
onChangeMaturity();
onChangeModelFolder();
+ onChangePBRFolder();
onChangeTextureFolder();
onChangeSoundFolder();
onChangeAnimationFolder();
@@ -938,7 +939,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
- LL_INFOS() << "Can't close preferences!" << LL_ENDL;
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@@ -1180,30 +1181,10 @@ void LLFloaterPreference::buildPopupLists()
void LLFloaterPreference::refreshEnabledState()
{
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
- // if vertex shaders off, disable all shader related products
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
- {
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
- }
- else
- {
- ctrl_wind_light->setEnabled(TRUE);
- }
-
- //Deferred/SSAO/Shadows
- BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
- BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- bumpshiny &&
- shaders &&
- gGLManager.mHasFramebufferObject &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
-
- ctrl_deferred->setEnabled(enabled);
+ //PBR
+ ctrl_pbr->setEnabled(TRUE);
// Cannot have floater active until caps have been received
getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
@@ -1213,59 +1194,19 @@ void LLFloaterPreference::refreshEnabledState()
void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
{
- LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
- LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
-
- // Reflections
- BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
- ctrl_reflections->setEnabled(reflections);
- reflections_text->setEnabled(reflections);
-
- // Bump & Shiny
- LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
- bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
- bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
-
- // Avatar Mode
- // Avatar Render Mode
- getChild<LLCheckBoxCtrl>("AvatarCloth")->setEnabled(TRUE);
-
- // Vertex Shaders, Global Shader Enable
- // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
- LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail"); // can be linked with control var
- LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
-
- terrain_detail->setEnabled(FALSE);
- terrain_text->setEnabled(FALSE);
-
// WindLight
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
- ctrl_wind_light->setEnabled(TRUE);
sky->setEnabled(TRUE);
sky_text->setEnabled(TRUE);
- //Deferred/SSAO/Shadows
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
-
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
- gGLManager.mHasFramebufferObject &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
-
- ctrl_deferred->setEnabled(enabled);
-
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
- // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
- enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+ BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO");
- ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
-
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
@@ -1276,23 +1217,11 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
// Hardware settings
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
- {
- getChildView("vbo")->setEnabled(FALSE);
- }
-
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
- !gGLManager.mHasVertexBufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures"))
{
getChildView("texture compression")->setEnabled(FALSE);
}
- // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
- LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
- gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
- getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
- getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
// now turn off any features that are unavailable
@@ -1343,11 +1272,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
{
- LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
- LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
- LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
@@ -1358,9 +1282,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
// disabled windlight
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
-
sky->setEnabled(FALSE);
sky_text->setEnabled(FALSE);
@@ -1374,14 +1295,10 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
ctrl_dof->setEnabled(FALSE);
ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
}
// disabled deferred
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
- !gGLManager.mHasFramebufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0);
@@ -1392,40 +1309,22 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
ctrl_dof->setEnabled(FALSE);
ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
}
- // disabled deferred SSAO
+ // disabled deferred SSAO
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
{
- ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setEnabled(FALSE);
ctrl_ssao->setValue(FALSE);
}
// disabled deferred shadows
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
- {
- ctrl_shadows->setEnabled(FALSE);
- ctrl_shadows->setValue(0);
- shadows_text->setEnabled(FALSE);
- }
-
- // disabled reflections
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
- {
- ctrl_reflections->setEnabled(FALSE);
- ctrl_reflections->setValue(FALSE);
- reflections_text->setEnabled(FALSE);
- }
-
- // disabled cloth
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
- {
- ctrl_avatar_cloth->setEnabled(FALSE);
- ctrl_avatar_cloth->setValue(FALSE);
- }
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
+ {
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+ shadows_text->setEnabled(FALSE);
+ }
}
void LLFloaterPreference::refresh()
@@ -1788,13 +1687,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
- LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@@ -1814,7 +1713,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
- LL_WARNS() << filename << " failed to load" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@@ -1884,6 +1783,14 @@ void LLFloaterPreference::onChangeModelFolder()
}
}
+void LLFloaterPreference::onChangePBRFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL));
+ }
+}
+
void LLFloaterPreference::onChangeTextureFolder()
{
if (gInventory.isInventoryUsable())
@@ -2720,7 +2627,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2747,7 +2654,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2853,7 +2760,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
@@ -2893,7 +2800,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
@@ -2948,10 +2855,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
}
}
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 5ef2ca68d3..af17c46be0 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
- void processProfileProperties(const LLAvatarData* pAvatarData );
- void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
@@ -174,6 +173,7 @@ public:
void applyResolution();
void onChangeMaturity();
void onChangeModelFolder();
+ void onChangePBRFolder();
void onChangeTextureFolder();
void onChangeSoundFolder();
void onChangeAnimationFolder();
@@ -213,7 +213,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
- LLAvatarData mAvatarProperties;
+ bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp
new file mode 100644
index 0000000000..6ccdace6c5
--- /dev/null
+++ b/indra/newview/llfloaterprofile.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file llfloaterprofile.cpp
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofile.h"
+
+#include "llagent.h" //gAgent
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+LLFloaterProfile::LLFloaterProfile(const LLSD& key)
+ : LLFloater(key),
+ mAvatarId(key["id"].asUUID()),
+ mNameCallbackConnection()
+{
+ mDefaultRectForGroup = false;
+}
+
+LLFloaterProfile::~LLFloaterProfile()
+{
+ if (mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection.disconnect();
+ }
+}
+
+void LLFloaterProfile::onOpen(const LLSD& key)
+{
+ mPanelProfile->onOpen(key);
+
+ // Update the avatar name.
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLFloaterProfile::postBuild()
+{
+ mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
+
+ return TRUE;
+}
+
+void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ if (mPanelProfile->hasUnpublishedClassifieds())
+ {
+ LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
+ }
+ else if (mPanelProfile->hasUnsavedChanges())
+ {
+ LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
+ }
+ else
+ {
+ closeFloater();
+ }
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (can_save)
+ {
+ // savable content
+
+ if (option == 0) // Save
+ {
+ mPanelProfile->commitUnsavedChanges();
+ closeFloater();
+ }
+ if (option == 1) // Discard
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+ else
+ {
+ // classifieds
+
+ if (option == 0) // Ok
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+
+}
+
+void LLFloaterProfile::createPick(const LLPickData &data)
+{
+ mPanelProfile->createPick(data);
+}
+
+void LLFloaterProfile::showPick(const LLUUID& pick_id)
+{
+ mPanelProfile->showPick(pick_id);
+}
+
+bool LLFloaterProfile::isPickTabSelected()
+{
+ return mPanelProfile->isPickTabSelected();
+}
+
+void LLFloaterProfile::refreshName()
+{
+ if (!mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+ }
+
+ LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
+ if (panel)
+ {
+ panel->refreshName();
+ }
+}
+
+void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
+{
+ mPanelProfile->showClassified(classified_id, edit);
+}
+
+void LLFloaterProfile::createClassified()
+{
+ mPanelProfile->createClassified();
+}
+
+void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mNameCallbackConnection.disconnect();
+ setTitle(av_name.getCompleteName());
+}
+
+// eof
diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h
new file mode 100644
index 0000000000..b3ed02fc2c
--- /dev/null
+++ b/indra/newview/llfloaterprofile.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloaterprofile.h
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILE_H
+#define LL_LLFLOATERPROFILE_H
+
+#include "llavatarnamecache.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloater.h"
+
+class LLPanelProfile;
+
+class LLFloaterProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterProfile);
+public:
+ LLFloaterProfile(const LLSD& key);
+ virtual ~LLFloaterProfile();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+ void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ void refreshName();
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+private:
+ LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ LLPanelProfile* mPanelProfile;
+
+ LLUUID mAvatarId;
+};
+
+#endif // LL_LLFLOATERPROFILE_H
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000..bf1f56a6d1
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+ : LLFloater(LLSD())
+ , mUpdateDimensions(TRUE)
+ , mLastHeight(0)
+ , mLastWidth(0)
+ , mImage(NULL)
+ , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+ mProfileIcon = getChild<LLIconCtrl>("profile_pic");
+
+ mCloseButton = getChild<LLButton>("close_btn");
+ mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+ if (mImage.isNull())
+ {
+ return;
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ return;
+ }
+
+ S32 img_width = mImage->getFullWidth();
+ S32 img_height = mImage->getFullHeight();
+
+ if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+ || mLastWidth != img_width
+ || mLastHeight != img_height)
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ // Asset has been fully loaded
+ mUpdateDimensions = TRUE;
+ }
+
+ mLastHeight = img_height;
+ mLastWidth = img_width;
+
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ LLRect old_floater_rect = getRect();
+ LLRect old_image_rect = mProfileIcon->getRect();
+ S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+ S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+ const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
+
+ S32 biggest_dim = llmax(width, height);
+ if (biggest_dim > MAX_DIMENTIONS)
+ {
+ F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
+ width *= scale_down;
+ height *= scale_down;
+ }
+
+ //reshape floater
+ reshape(width, height);
+
+ gFloaterView->adjustToFitScreen(this, FALSE);
+ }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::onOpen(const LLSD& key)
+{
+ mCloseButton->setFocus(true);
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+ mProfileIcon->setValue("Generic_Person_Large");
+ mImageID = LLUUID::null;
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+ if (mImageID != image_id)
+ {
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ mProfileIcon->setValue(image_id);
+ mImageID = image_id;
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImageOldBoostLevel = mImage->getBoostLevel();
+
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+ 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
+
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ }
+
+ mUpdateDimensions = TRUE;
+ updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
+ if (floater && success)
+ {
+ floater->mUpdateDimensions = TRUE;
+ floater->updateDimensions();
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000..66a61213dd
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+ LLFloaterProfileTexture(LLView* owner);
+ ~LLFloaterProfileTexture();
+
+ void draw() override;
+ void onOpen(const LLSD& key) override;
+
+ void resetAsset();
+ void loadAsset(const LLUUID &image_id);
+
+
+ static void onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+protected:
+ BOOL postBuild() override;
+
+private:
+ void updateDimensions();
+
+ LLUUID mImageID;
+ LLPointer<LLViewerFetchedTexture> mImage;
+ S32 mImageOldBoostLevel;
+ S32 mAssetStatus;
+ F32 mContextConeOpacity;
+ S32 mLastHeight;
+ S32 mLastWidth;
+ BOOL mUpdateDimensions;
+
+ LLHandle<LLView> mOwnerHandle;
+ LLIconCtrl* mProfileIcon;
+ LLButton* mCloseButton;
+
+ LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 19080f05c0..07d4dcae38 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
#include "llbutton.h"
@@ -1322,6 +1323,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
+ static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@@ -1343,17 +1345,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
- if (width > 512 || height > 512)
+ if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@@ -1826,7 +1830,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
setCtrlsEnabled(god || owner || manager);
getChildView("apply_btn")->setEnabled(FALSE);
-
+ getChildView("estate_owner")->setEnabled(TRUE);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
@@ -1888,6 +1892,8 @@ BOOL LLPanelEstateInfo::postBuild()
getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
+
return LLPanelRegionInfo::postBuild();
}
@@ -2108,6 +2114,8 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text");
region_landtype->setText(region->getLocalizedSimProductName());
+
+ getChild<LLButton>("reset_covenant")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate()));
// let the parent class handle the general data collection.
bool rv = LLPanelRegionInfo::refreshFromRegion(region);
@@ -2132,6 +2140,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");
@@ -3681,7 +3690,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
- listCtrl->selectItemByPrefix(search_string, FALSE);
+ listCtrl->searchItems(search_string, false, true);
}
else
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index b73755cf4e..2df4ca973d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
- std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
- mMCDList.clear();
-
delete mResourceDatap;
}
@@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
+// static
+void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
+{
+ show(avatar_id, avatar_name);
+
+ LLStringUtil::format_map_t args;
+ args["[MSG_TIME]"] = time;
+ args["[MSG_DESCRIPTION]"] = description;
+
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ if (self)
+ {
+ std::string description = self->getString("chat_report_format", args);
+ self->getChild<LLUICtrl>("details_edit")->setValue(description);
+ }
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild<LLUICtrl>("object_name")->setValue(object_name);
@@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
-
-
-// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// self->getChild<LLUICtrl>("details_edit")->setValue(description);
-
-// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
-// self->mMCDList.clear();
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
-
-// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
-// if (text)
-// {
-// text->insertText(description);
-// }
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index c678df7155..b6c70e866d 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -93,6 +93,7 @@ public:
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
+ static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description);
static void showFromExperience(const LLUUID& experience_id);
static void onClickSend (void *userdata);
@@ -101,8 +102,6 @@ public:
void onClickSelectAbuser ();
static void closePickTool (void *userdata);
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
- static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
- static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
@@ -114,10 +113,8 @@ private:
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
void takeScreenshot(bool use_prev_screenshot = false);
- void sendReportViaCaps(std::string url);
void uploadImage();
bool validateReport();
- void setReporterID();
LLSD gatherReport();
void sendReportViaLegacy(const LLSD & report);
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
@@ -144,7 +141,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
- std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2e1fbb09e0..bb3ed77772 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -57,10 +57,10 @@ public:
const size_t parts = tokens.size();
// get the (optional) category for the search
- std::string category;
+ std::string collection;
if (parts > 0)
{
- category = tokens[0].asString();
+ collection = tokens[0].asString();
}
// get the (optional) search string
@@ -72,7 +72,7 @@ public:
// create the LLSD arguments for the search floater
LLFloaterSearch::Params p;
- p.search.category = category;
+ p.search.collection = collection;
p.search.query = LLURI::unescape(search_text);
// open the search floater and perform the requested search
@@ -83,8 +83,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
-: category("category", ""),
- query("query")
+: category("category", ""),
+ collection("collection", ""),
+ query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@@ -93,16 +94,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
- mCategoryPaths = LLSD::emptyMap();
- mCategoryPaths["all"] = "search";
- mCategoryPaths["people"] = "search/people";
- mCategoryPaths["places"] = "search/places";
- mCategoryPaths["events"] = "search/events";
- mCategoryPaths["groups"] = "search/groups";
- mCategoryPaths["wiki"] = "search/wiki";
- mCategoryPaths["land"] = "land";
- mCategoryPaths["destinations"] = "destinations";
- mCategoryPaths["classifieds"] = "classifieds";
+
+ mSearchType.insert("standard");
+ mSearchType.insert("land");
+ mSearchType.insert("classified");
+
+ mCollectionType.insert("events");
+ mCollectionType.insert("destinations");
+ mCollectionType.insert("places");
+ mCollectionType.insert("groups");
+ mCollectionType.insert("people");
}
BOOL LLFloaterSearch::postBuild()
@@ -157,31 +158,49 @@ void LLFloaterSearch::search(const SearchQuery &p)
// work out the subdir to use based on the requested category
LLSD subs;
- if (mCategoryPaths.has(p.category))
+ if (mSearchType.find(p.category) != mSearchType.end())
{
- subs["CATEGORY"] = mCategoryPaths[p.category].asString();
+ subs["TYPE"] = p.category;
}
else
{
- subs["CATEGORY"] = mCategoryPaths["all"].asString();
+ subs["TYPE"] = "standard";
}
// add the search query string
subs["QUERY"] = LLURI::escape(p.query);
+ subs["COLLECTION"] = "";
+ if (subs["TYPE"] == "standard")
+ {
+ if (mCollectionType.find(p.collection) != mCollectionType.end())
+ {
+ subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
+ }
+ else
+ {
+ std::string collection_args("");
+ for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
+ {
+ collection_args += "&collection_chosen=" + std::string(*it);
+ }
+ subs["COLLECTION"] = collection_args;
+ }
+ }
+
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
if (gAgent.prefersAdult())
{
- maturity = "42"; // PG,Mature,Adult
+ maturity = "gma"; // PG,Mature,Adult
}
else if (gAgent.prefersMature())
{
- maturity = "21"; // PG,Mature
+ maturity = "gm"; // PG,Mature
}
else
{
- maturity = "13"; // PG
+ maturity = "g"; // PG
}
subs["MATURITY"] = maturity;
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..cc77ce696f 100644
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
@@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block<SearchQuery>
{
Optional<std::string> category;
+ Optional<std::string> collection;
Optional<std::string> query;
SearchQuery();
@@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
- LLSD mCategoryPaths;
+ std::set<std::string> mSearchType;
+ std::set<std::string> mCollectionType;
U8 mSearchGodLevel;
};
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index de5d59f484..32eb70cd39 100644
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -259,7 +259,7 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void)
void LLFloaterSpellCheckerImport::onBtnBrowse()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false);
}
void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 0429749e11..b6acba6558 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -46,7 +46,6 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
-#include "llmediactrl.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
@@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild()
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
- mTitleMedia = getChild<LLMediaCtrl>("title_media");
mBtnLink = getChild<LLButton>("link_btn");
mBtnUnlink = getChild<LLButton>("unlink_btn");
@@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
- mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
- mHasSelection(TRUE),
- mNeedMediaTitle(TRUE)
+ mHasSelection(TRUE)
{
gFloaterTools = this;
@@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
- mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
@@ -480,30 +473,61 @@ void LLFloaterTools::refresh()
else
#endif
{
- F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
- S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ F32 link_cost = selection->getSelectedLinksetCost();
+ S32 link_count = selection->getRootObjectCount();
+ S32 object_count = selection->getObjectCount();
- LLCrossParcelFunctor func;
- if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
- {
- // Selection crosses parcel bounds.
- // We don't display remaining land capacity in this case.
- const LLStringExplicit empty_str("");
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str);
- }
- else
- {
- LLViewerObject* selected_object = mObjectSelection->getFirstObject();
- if (selected_object)
- {
- // Select a parcel at the currently selected object's position.
- LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
- }
- else
- {
- LL_WARNS() << "Failed to get selected object" << LL_ENDL;
- }
- }
+ LLCrossParcelFunctor func;
+ if (!LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
+ {
+ // Unless multiple parcels selected, higlight parcel object is at.
+ LLViewerObject* selected_object = mObjectSelection->getFirstObject();
+ if (selected_object)
+ {
+ // Select a parcel at the currently selected object's position.
+ LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
+ }
+ else
+ {
+ LL_WARNS() << "Failed to get selected object" << LL_ENDL;
+ }
+ }
+
+ if (object_count == 1)
+ {
+ // "selection_faces" shouldn't be visible if not LLToolFace::getInstance()
+ // But still need to be populated in case user switches
+
+ std::string faces_str = "";
+
+ for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end();)
+ {
+ LLObjectSelection::iterator nextiter = iter++; // not strictly needed, we have only one object
+ LLSelectNode* node = *nextiter;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ if (!faces_str.empty())
+ {
+ faces_str += ", ";
+ }
+ faces_str += llformat("%d", te);
+ }
+ }
+ }
+
+ childSetTextArg("selection_faces", "[FACES_STRING]", faces_str);
+ }
+
+ bool show_faces = (object_count == 1)
+ && LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ getChildView("selection_faces")->setVisible(show_faces);
LLStringUtil::format_map_t selection_args;
selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
@@ -522,7 +546,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
- refreshMedia();
+ mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
@@ -549,9 +573,6 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
- // grab media name/title and update the UI widget
- updateMediaTitle();
-
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -824,7 +845,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
- getChildView("remaining_capacity")->setVisible(!land_visible && have_selection);
+ getChildView("selection_faces")->setVisible(LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()
+ && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
@@ -874,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
- if( mTitleMedia )
- mTitleMedia->unloadMediaSource();
+ mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
@@ -1095,7 +1116,7 @@ void LLFloaterTools::onClickGridOptions()
{
LLFloater* floaterp = LLFloaterReg::showInstance("build_options");
// position floater next to build tools, not over
- floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
+ floaterp->setShape(gFloaterView->findNeighboringPosition(this, floaterp), true);
}
// static
@@ -1128,51 +1149,6 @@ void LLFloaterTools::onFocusReceived()
LLFloater::onFocusReceived();
}
-// Media stuff
-void LLFloaterTools::refreshMedia()
-{
- getMediaState();
-}
-
-bool LLFloaterTools::selectedMediaEditable()
-{
- U32 owner_mask_on;
- U32 owner_mask_off;
- U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
- &owner_mask_on, &owner_mask_off );
- U32 group_mask_on;
- U32 group_mask_off;
- U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
- &group_mask_on, &group_mask_off );
- U32 everyone_mask_on;
- U32 everyone_mask_off;
- S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
- &everyone_mask_on, &everyone_mask_off );
-
- bool selected_Media_editable = false;
-
- // if perms we got back are valid
- if ( valid_owner_perms &&
- valid_group_perms &&
- valid_everyone_perms )
- {
-
- if ( ( owner_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) )
- {
- selected_Media_editable = true;
- }
- else
- // user is NOT allowed to press the RESET button
- {
- selected_Media_editable = false;
- };
- };
-
- return selected_Media_editable;
-}
-
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
@@ -1181,26 +1157,6 @@ void LLFloaterTools::updateLandImpacts()
return;
}
- S32 rezzed_prims = parcel->getSimWidePrimCount();
- S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (region)
- {
- S32 max_tasks_per_region = (S32)region->getMaxTasks();
- total_capacity = llmin(total_capacity, max_tasks_per_region);
- }
- std::string remaining_capacity_str = "";
-
- bool show_mesh_cost = gMeshRepo.meshRezEnabled();
- if (show_mesh_cost)
- {
- LLStringUtil::format_map_t remaining_capacity_args;
- remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims);
- remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args);
- }
-
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str);
-
// Update land impacts info in the weights floater
LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater)
@@ -1209,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts()
}
}
-void LLFloaterTools::getMediaState()
-{
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* first_object = selected_objects->getFirstObject();
- LLTextBox* media_info = getChild<LLTextBox>("media_info");
-
- if( !(first_object
- && first_object->getPCode() == LL_PCODE_VOLUME
- &&first_object->permModify()
- ))
- {
- getChildView("add_media")->setEnabled(FALSE);
- media_info->clear();
- clearMediaSettings();
- return;
- }
-
- std::string url = first_object->getRegion()->getCapability("ObjectMedia");
- bool has_media_capability = (!url.empty());
-
- if(!has_media_capability)
- {
- getChildView("add_media")->setEnabled(FALSE);
- LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
- clearMediaSettings();
- return;
- }
-
- BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
- && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
- bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
-
- // Check modify permissions and whether any selected objects are in
- // the process of being fetched. If they are, then we're not editable
- if (editable)
- {
- LLObjectSelection::iterator iter = selected_objects->begin();
- LLObjectSelection::iterator end = selected_objects->end();
- for ( ; iter != end; ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
- if (NULL != object)
- {
- if (!object->permModify())
- {
- LL_INFOS("LLFloaterToolsMedia")
- << "Selection not editable due to lack of modify permissions on object id "
- << object->getID() << LL_ENDL;
-
- editable = false;
- break;
- }
- // XXX DISABLE this for now, because when the fetch finally
- // does come in, the state of this floater doesn't properly
- // update. Re-selecting fixes the problem, but there is
- // contention as to whether this is a sufficient solution.
-// if (object->isMediaDataBeingFetched())
-// {
-// LL_INFOS("LLFloaterToolsMedia")
-// << "Selection not editable due to media data being fetched for object id "
-// << object->getID() << LL_ENDL;
-//
-// editable = false;
-// break;
-// }
- }
- }
- }
-
- // Media settings
- bool bool_has_media = false;
- struct media_functor : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- LLTextureEntry *te = object->getTE(face);
- if (te)
- {
- return te->hasMedia();
- }
- return false;
- }
- } func;
-
-
- // check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
-
- const LLMediaEntry default_media_data;
-
- struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
- {
- functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- LLMediaEntry get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return *(object->getTE(face)->getMediaData());
- return mMediaEntry;
- };
-
- const LLMediaEntry& mMediaEntry;
-
- } func_media_data(default_media_data);
-
- LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
-
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- std::string media_title = "";
- // update UI depending on whether "object" (prim or face) has media
- // and whether or not you are allowed to edit it.
-
- getChildView("add_media")->setEnabled(editable);
- // IF all the faces have media (or all dont have media)
- if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
- {
- // TODO: get media title and set it.
- media_info->clear();
- // if identical is set, all faces are same (whether all empty or has the same media)
- if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- // else all faces might be empty.
- }
- else // there' re Different Medias' been set on on the faces.
- {
- media_title = multi_media_info_str;
- }
-
- getChildView("delete_media")->setEnabled(bool_has_media && editable );
- // TODO: display a list of all media on the face - use 'identical' flag
- }
- else // not all face has media but at least one does.
- {
- // seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
-
- if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
- {
- media_title = multi_media_info_str;
- }
- else
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- }
-
- getChildView("delete_media")->setEnabled(TRUE);
- }
-
- navigateToTitleMedia(media_title);
- media_info->setText(media_title);
-
- // load values for media settings
- updateMediaSettings();
-
- LLFloaterMediaSettings::initValues(mMediaSettings, editable );
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to add media to a prim or prim face
-void LLFloaterTools::onClickBtnAddMedia()
-{
- // check if multiple faces are selected
- if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
- {
- LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
- }
- else
- {
- onClickBtnEditMedia();
- }
-}
-
-// static
-bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- gFloaterTools->onClickBtnEditMedia();
- break;
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to edit existing media settings on a prim or prim face
-// TODO: test if there is media on the item and only allow editing if present
-void LLFloaterTools::onClickBtnEditMedia()
-{
- refreshMedia();
- LLFloaterReg::showInstance("media_settings");
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to delete media from a prim or prim face
-void LLFloaterTools::onClickBtnDeleteMedia()
-{
- LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
-}
-
-
-// static
-bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
- if(LLFloaterReg::instanceVisible("media_settings"))
- {
- LLFloaterReg::hideInstance("media_settings");
- }
- break;
-
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::clearMediaSettings()
-{
- LLFloaterMediaSettings::clearValues(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::navigateToTitleMedia( const std::string url )
-{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-
- if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
- {
- // if it's a movie, we don't want to hear it
- media_plugin->setVolume( 0 );
- };
-
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
- }
-
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaTitle()
-{
- // only get the media name if we need it
- if ( ! mNeedMediaTitle )
- return;
-
- // get plugin impl
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- if ( media_plugin )
- {
- // get the media name (asynchronous - must call repeatedly)
- std::string media_title = media_plugin->getMediaName();
-
- // only replace the title if what we get contains something
- if ( ! media_title.empty() )
- {
- // update the UI widget
- LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
- if ( media_title_field )
- {
- media_title_field->setText( media_title );
-
- // stop looking for a title when we get one
- // FIXME: check this is the right approach
- mNeedMediaTitle = false;
- };
- };
- };
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaSettings()
-{
- bool identical( false );
- std::string base_key( "" );
- std::string value_str( "" );
- int value_int = 0;
- bool value_bool = false;
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- // TODO: (CP) refactor this using something clever or boost or both !!
-
- const LLMediaEntry default_media_data;
-
- // controls
- U8 value_u8 = default_media_data.getControls();
- struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
- {
- functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
-
- U8 get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getControls();
- return mMediaEntry.getControls();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_controls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
- base_key = std::string( LLMediaEntry::CONTROLS_KEY );
- mMediaSettings[ base_key ] = value_u8;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // First click (formerly left click)
- value_bool = default_media_data.getFirstClickInteract();
- struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getFirstClickInteract();
- return mMediaEntry.getFirstClickInteract();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_first_click(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
- base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Home URL
- value_str = default_media_data.getHomeURL();
- struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHomeURL();
- return mMediaEntry.getHomeURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_home_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
- base_key = std::string( LLMediaEntry::HOME_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Current URL
- value_str = default_media_data.getCurrentURL();
- struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getCurrentURL();
- return mMediaEntry.getCurrentURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_current_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
- base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto zoom
- value_bool = default_media_data.getAutoZoom();
- struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
- {
-
- functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoZoom();
- return mMediaEntry.getAutoZoom();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_zoom(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto play
- //value_bool = default_media_data.getAutoPlay();
- // set default to auto play TRUE -- angela EXT-5172
- value_bool = true;
- struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoPlay();
- //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_play(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
-
- // Auto scale
- // set default to auto scale TRUE -- angela EXT-5172
- //value_bool = default_media_data.getAutoScale();
- value_bool = true;
- struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoScale();
- // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_scale(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto loop
- value_bool = default_media_data.getAutoLoop();
- struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoLoop();
- return mMediaEntry.getAutoLoop();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_loop(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // width pixels (if not auto scaled)
- value_int = default_media_data.getWidthPixels();
- struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWidthPixels();
- return mMediaEntry.getWidthPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_width_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
- base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // height pixels (if not auto scaled)
- value_int = default_media_data.getHeightPixels();
- struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHeightPixels();
- return mMediaEntry.getHeightPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_height_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
- base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Enable Alt image
- value_bool = default_media_data.getAltImageEnable();
- struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAltImageEnable();
- return mMediaEntry.getAltImageEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_enable_alt_image(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
- base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_control(default_media_data);
- identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_interact(default_media_data);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist enable
- value_bool = default_media_data.getWhiteListEnable();
- struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteListEnable();
- return mMediaEntry.getWhiteListEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_enable(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
- base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist URLs
- std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
- struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
- {
- functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::vector<std::string> get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteList();
- return mMediaEntry.getWhiteList();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_urls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
- base_key = std::string( LLMediaEntry::WHITELIST_KEY );
- mMediaSettings[ base_key ].clear();
- std::vector< std::string >::iterator iter = value_vector_str.begin();
- while( iter != value_vector_str.end() )
- {
- std::string white_list_url = *iter;
- mMediaSettings[ base_key ].append( white_list_url );
- ++iter;
- };
-
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-}
-
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ffff564ad4..3bb6492a6e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
-class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -98,11 +97,6 @@ public:
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
- void onClickBtnDeleteMedia();
- void onClickBtnAddMedia();
- void onClickBtnEditMedia();
- void clearMediaSettings();
- bool selectedMediaEditable();
void updateLandImpacts();
static void setGridMode(S32 mode);
@@ -111,13 +105,6 @@ public:
private:
void refresh();
- void refreshMedia();
- void getMediaState();
- void updateMediaSettings();
- void navigateToTitleMedia( const std::string url ); // navigate if changed
- void updateMediaTitle();
- static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
- static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
@@ -193,19 +180,12 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
- LLMediaCtrl *mTitleMedia;
- bool mNeedMediaTitle;
-
private:
BOOL mDirty;
BOOL mHasSelection;
std::map<std::string, std::string> mStatusText;
-
-protected:
- LLSD mMediaSettings;
-
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index e67c79a3a0..67a205417e 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -1023,7 +1023,7 @@ void LLFloaterUIPreview::onClickEditFloater()
void LLFloaterUIPreview::onClickBrowseForEditor()
{
// Let the user choose an executable through the file picker dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false);
}
void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
@@ -1077,7 +1077,7 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen
void LLFloaterUIPreview::onClickBrowseForDiffs()
{
// create load dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index d5c2ad5f81..917d6dfcd0 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
- else
- {
- LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
- if(panel_face)
- {
- panel_face->setMediaType(mime_type);
- panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
- }
-
- }
getChildView("loading_label")->setVisible( false);
closeFloater();
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 59e1f49f81..23f19dd5aa 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(data);
getChild<LLUICtrl>("avatar_name")->setValue("");
updateVolumeControls();
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
deleted file mode 100644
index 891bb90c0e..0000000000
--- a/indra/newview/llfloaterwebprofile.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file llfloaterwebprofile.cpp
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterwebprofile.h"
-
-#include "llviewercontrol.h"
-
-LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
- LLFloaterWebContent(key)
-{
-}
-
-void LLFloaterWebProfile::onOpen(const LLSD& key)
-{
- Params p(key);
- p.show_chrome(true);
- p.window_class("profile");
- p.allow_address_entry(false);
- p.trusted_content(true);
- LLFloaterWebContent::onOpen(p);
- applyPreferredRect();
-}
-
-// virtual
-void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
-{
- LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
-
- if (by_user && !isMinimized())
- {
- LL_DEBUGS() << "Storing new rect" << LL_ENDL;
- gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
- }
-
- LLFloaterWebContent::handleReshape(new_rect, by_user);
-}
-
-LLFloater* LLFloaterWebProfile::create(const LLSD& key)
-{
- LLFloaterWebContent::Params p(key);
- preCreate(p);
- return new LLFloaterWebProfile(p);
-}
-
-void LLFloaterWebProfile::applyPreferredRect()
-{
- const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
- LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
-
- // Don't override position that may have been set by floater stacking code.
- LLRect new_rect = getRect();
- new_rect.setLeftTopAndSize(
- new_rect.mLeft, new_rect.mTop,
- preferred_rect.getWidth(), preferred_rect.getHeight());
- setShape(new_rect);
-}
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterwebprofile.h
deleted file mode 100644
index 4c355e401b..0000000000
--- a/indra/newview/llfloaterwebprofile.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file llfloaterwebprofile.h
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLFLOATERWEBPROFILE_H
-#define LL_LLFLOATERWEBPROFILE_H
-
-#include "llfloaterwebcontent.h"
-#include "llviewermediaobserver.h"
-
-#include <string>
-
-class LLMediaCtrl;
-
-/**
- * Displays avatar profile web page.
- */
-class LLFloaterWebProfile
-: public LLFloaterWebContent
-{
- LOG_CLASS(LLFloaterWebProfile);
-public:
- typedef LLFloaterWebContent::Params Params;
-
- LLFloaterWebProfile(const Params& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
-
- static LLFloater* create(const LLSD& key);
-
-private:
- void applyPreferredRect();
-};
-
-#endif // LL_LLFLOATERWEBPROFILE_H
-
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 2c84cd1f93..01bfae8934 100644..100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -45,6 +45,7 @@
//#include "llfirstuse.h"
#include "llfloaterreg.h" // getTypedInstance()
#include "llfocusmgr.h"
+#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -81,7 +82,6 @@
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
-static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
@@ -284,7 +284,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
BOOL LLFloaterWorldMap::postBuild()
{
- mPanel = getChild<LLPanel>("objects_mapview");
+ mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@@ -305,13 +305,13 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
- mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
- getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
+ F32 slider_zoom = mMapView->getZoom();
+ getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
+
+ getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
setDefaultBtn(NULL);
- mZoomTimer.stop();
-
onChangeMaturity();
return TRUE;
@@ -321,7 +321,7 @@ BOOL LLFloaterWorldMap::postBuild()
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
- mPanel = NULL;
+ mMapView = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
@@ -359,17 +359,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
mIsClosing = FALSE;
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->clearLastClick();
+ mMapView->clearLastClick();
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, true);
}
- map_panel->updateVisibleBlocks();
+ mMapView->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
@@ -417,18 +415,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (!isMinimized() && isFrontmost())
- {
- if(mPanel->pointInView(x, y))
- {
- F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal();
- slider_value += ((F32)clicks * -0.3333f);
- getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value));
- return TRUE;
- }
- }
-
- return LLFloater::handleScrollWheel(x, y, clicks);
+ if (!isMinimized() && isFrontmost())
+ {
+ S32 map_x = x - mMapView->getRect().mLeft;
+ S32 map_y = y - mMapView->getRect().mBottom;
+ if (mMapView->pointInView(map_x, map_y))
+ {
+ F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal();
+ F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
+ getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom));
+ mMapView->zoomWithPivot(slider_zoom, map_x, map_y);
+ return true;
+ }
+ }
+
+ return LLFloater::handleScrollWheel(x, y, clicks);
}
@@ -507,26 +508,13 @@ void LLFloaterWorldMap::draw()
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
-
- //RN: snaps to zoom value because interpolation caused jitter in the text rendering
- if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
- {
- mZoomTimer.start();
- }
- F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
- if (interp > 1.f)
- {
- interp = 1.f;
- mZoomTimer.stop();
- }
- mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
- F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
- LLWorldMapView::setScale( map_scale );
+
+ mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());
// Enable/disable checkboxes depending on the zoom level
// If above threshold level (i.e. low res) -> Disable all checkboxes
// If under threshold level (i.e. high res) -> Enable all checkboxes
- bool enable = LLWorldMapView::showRegionInfo();
+ bool enable = mMapView->showRegionInfo();
getChildView("people_chk")->setEnabled(enable);
getChildView("infohub_chk")->setEnabled(enable);
getChildView("telehub_chk")->setEnabled(enable);
@@ -1005,7 +993,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
- if (list)
+ if (list && list->getSelectedValue().asString() != "None")
{
list->selectByValue( "None" );
}
@@ -1025,9 +1013,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)mPanel;
- LLRect view_rect = map_panel->getRect();
+ LLRect view_rect = mMapView->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
@@ -1295,9 +1281,9 @@ void LLFloaterWorldMap::onShowTargetBtn()
void LLFloaterWorldMap::onShowAgentBtn()
{
- LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
- // Set flag so user's location will be displayed if not tracking anything else
- mSetToUserPosition = TRUE;
+ mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate
+ // Set flag so user's location will be displayed if not tracking anything else
+ mSetToUserPosition = true;
}
void LLFloaterWorldMap::onClickTeleportBtn()
@@ -1315,6 +1301,22 @@ void LLFloaterWorldMap::onCopySLURL()
LLNotificationsUtil::add("CopySLURL", args);
}
+void LLFloaterWorldMap::onExpandCollapseBtn()
+{
+ LLLayoutStack* floater_stack = getChild<LLLayoutStack>("floater_map_stack");
+ LLLayoutPanel* controls_panel = getChild<LLLayoutPanel>("controls_lp");
+
+ bool toggle_collapse = !controls_panel->isCollapsed();
+ floater_stack->collapsePanel(controls_panel, toggle_collapse);
+ floater_stack->updateLayout();
+
+ std::string image_name = getString(toggle_collapse ? "expand_icon" : "collapse_icon");
+ std::string tooltip = getString(toggle_collapse ? "expand_tooltip" : "collapse_tooltip");
+ getChild<LLIconCtrl>("expand_collapse_icon")->setImage(LLUI::getUIImage(image_name));
+ getChild<LLIconCtrl>("expand_collapse_icon")->setToolTip(tooltip);
+ getChild<LLPanel>("expand_btn_panel")->setToolTip(tooltip);
+}
+
// protected
void LLFloaterWorldMap::centerOnTarget(BOOL animate)
{
@@ -1349,9 +1351,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
pos_global.clearVec();
}
- LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- !animate);
+ F64 map_scale = (F64)mMapView->getScale();
+ mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)),
+ -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)),
+ !animate, 0.1f);
mWaitingForTracker = FALSE;
}
@@ -1581,7 +1584,7 @@ void LLFloaterWorldMap::onTeleportFinished()
{
if(isInVisibleChain())
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, TRUE);
}
}
@@ -1656,9 +1659,8 @@ void LLFloaterWorldMap::onChangeMaturity()
void LLFloaterWorldMap::onFocusLost()
{
- gViewerWindow->showCursor();
- LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->mPanning = FALSE;
+ gViewerWindow->showCursor();
+ mMapView->mPanning = false;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 14a9c26fb9..3702226d23 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -44,6 +44,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
+class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
@@ -130,6 +131,8 @@ protected:
void onShowAgentBtn();
void onCopySLURL();
+ void onExpandCollapseBtn();
+
void centerOnTarget(BOOL animate);
void updateLocation();
@@ -154,11 +157,7 @@ protected:
void onTeleportFinished();
private:
- LLPanel* mPanel; // Panel displaying the map
-
- // Ties to LLWorldMapView::sMapScale, in pixels per region
- F32 mCurZoomVal;
- LLFrameTimer mZoomTimer;
+ LLWorldMapView* mMapView; // Panel displaying the map
// update display of teleport destination coordinates - pos is in global coordinates
void updateTeleportCoordsDisplay( const LLVector3d& pos );
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0be748ace9..e395da7f1e 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders()
/************************************************************************/
/* Private Methods */
/************************************************************************/
-const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
+const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const
{
- const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ if (parent_id.isNull())
+ {
+ return LLUUID::null;
+ }
- std::string friendFolderName = get_friend_folder_name();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(parent_id, cats, items);
- return findChildFolderUUID(callingCardsFolderID, friendFolderName);
+ if (!cats || !items || cats->size() == 0)
+ {
+ // call failed
+ return LLUUID::null;
+ }
+
+ if (cats->size() > 1)
+ {
+ const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id);
+ if (friendFolder)
+ {
+ LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL;
+ }
+ }
+
+ for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin();
+ iter != cats->end();
+ ++iter)
+ {
+ const LLInventoryCategory* category = (*iter);
+ if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD)
+ {
+ return category->getUUID();
+ }
+ }
+
+ return LLUUID::null;
}
-const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+// Inventorry ->
+// Calling Cards - >
+// Friends - > (the only expected folder)
+// All (the only expected folder)
+
+const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
- LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+ return findFirstCallingCardSubfolder(callingCardsFolderID);
+}
- std::string friendAllSubfolderName = get_friend_all_subfolder_name();
+const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+{
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
- return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
+ return findFirstCallingCardSubfolder(friendFolderUUID);
}
const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 2fb912a930..f5679d7d85 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -116,6 +116,7 @@ private:
}
const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const;
+ const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const;
const LLUUID& findFriendFolderUUIDImpl() const;
const LLUUID& findFriendAllSubfolderUUIDImpl() const;
const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 91ab445273..7c8e8279c2 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -185,7 +185,7 @@ private:
std::set<LLUUID> mLoadingAssets;
// LLEventHost interface
- boost::shared_ptr<LLGestureListener> mListener;
+ std::shared_ptr<LLGestureListener> mListener;
};
#endif
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 175f1849cf..38ec24cae8 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -987,9 +987,8 @@ private:
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{
- if (!gGLManager.mHasTimerQuery)
+ if (gGLManager.mGLVersion < 3.3f)
{ // don't bother benchmarking venerable drivers which don't support accurate timing anyway
- // and are likely to be correctly identified by the GPU table already.
return -1.f;
}
@@ -1000,8 +999,8 @@ F32 gpu_benchmark()
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mFeatures.attachNothing = true;
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = 1;
if (!gBenchmarkProgram.createShader(NULL, NULL))
{
@@ -1084,7 +1083,7 @@ F32 gpu_benchmark()
delete [] pixels;
//make a dummy triangle to draw with
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW_ARB);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW);
if (!buff->allocateBuffer(3, 0, true))
{
@@ -1115,16 +1114,6 @@ F32 gpu_benchmark()
// ensure matched pair of bind() and unbind() calls
ShaderBinder binder(gBenchmarkProgram);
-#ifdef GL_ARB_vertex_array_object
- U32 glarray = 0;
-
- if (LLRender::sGLCoreProfile)
- {
- glGenVertexArrays(1, &glarray);
- glBindVertexArray(glarray);
- }
-#endif
-
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
@@ -1157,15 +1146,6 @@ F32 gpu_benchmark()
}
}
-#ifdef GL_ARB_vertex_array_object
- if (LLRender::sGLCoreProfile)
- {
- glBindVertexArray(0);
- glDeleteVertexArrays(1, &glarray);
- }
-#endif
-
-
std::sort(results.begin(), results.end());
F32 gbps = results[results.size()/2];
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
new file mode 100644
index 0000000000..05ed7a2019
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -0,0 +1,298 @@
+/**
+ * @file llgltfmateriallist.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgltfmateriallist.h"
+
+#include "llassetstorage.h"
+#include "lldispatcher.h"
+#include "llfetchedgltfmaterial.h"
+#include "llfilesystem.h"
+#include "llsdserialize.h"
+#include "lltinygltfhelper.h"
+#include "llviewercontrol.h"
+#include "llviewergenericmessage.h"
+#include "llviewerobjectlist.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include <strstream>
+
+#include "json/reader.h"
+#include "json/value.h"
+
+LLGLTFMaterialList gGLTFMaterialList;
+
+namespace
+{
+ class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler
+ {
+ LOG_CLASS(LLGLTFMaterialOverrideDispatchHandler);
+ public:
+ LLGLTFMaterialOverrideDispatchHandler() = default;
+ ~LLGLTFMaterialOverrideDispatchHandler() override = default;
+
+ bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
+ {
+ // receive override data from simulator via LargeGenericMessage
+ // message should have:
+ // object_id - UUID of LLViewerObject
+ // side - S32 index of texture entry
+ // gltf_json - String of GLTF json for override data
+
+
+ LLSD message;
+
+ sparam_t::const_iterator it = strings.begin();
+ if (it != strings.end()) {
+ const std::string& llsdRaw = *it++;
+ std::istringstream llsdData(llsdRaw);
+ if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
+ {
+ LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ }
+ }
+
+ LLUUID object_id = message["object_id"].asUUID();
+
+ LLViewerObject * obj = gObjectList.findObject(object_id);
+ S32 side = message["side"].asInteger();
+ std::string gltf_json = message["gltf_json"].asString();
+
+ std::string warn_msg, error_msg;
+ LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
+ bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg);
+
+ if (!success)
+ {
+ LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
+ }
+ else
+ {
+ if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data))
+ {
+ // object not ready to receive override data, queue for later
+ gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data);
+ }
+ }
+
+ return true;
+ }
+ };
+ LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message;
+}
+
+void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data)
+{
+ override_list_t& overrides = mQueuedOverrides[id];
+
+ if (overrides.size() < side + 1)
+ {
+ overrides.resize(side + 1);
+ }
+
+ overrides[side] = override_data;
+}
+
+void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
+{
+ const LLUUID& id = obj->getID();
+ auto iter = mQueuedOverrides.find(id);
+
+ if (iter != mQueuedOverrides.end())
+ {
+ override_list_t& overrides = iter->second;
+ for (int i = 0; i < overrides.size(); ++i)
+ {
+ if (overrides[i].notNull())
+ {
+ if (!obj->getTE(i)->getGLTFMaterial())
+ { // object doesn't have its base GLTF material yet, don't apply override (yet)
+ return;
+ }
+ obj->setTEGLTFMaterialOverride(i, overrides[i]);
+ }
+ }
+
+ mQueuedOverrides.erase(iter);
+ }
+}
+
+LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+{
+ uuid_mat_map_t::iterator iter = mList.find(id);
+ if (iter == mList.end())
+ {
+ LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();
+ mList[id] = mat;
+
+ if (!mat->mFetching)
+ {
+ // if we do multiple getAssetData calls,
+ // some will get distched, messing ref counter
+ // Todo: get rid of mat->ref()
+ mat->mFetching = true;
+ mat->ref();
+
+ gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL,
+ [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)
+ {
+ if (status)
+ {
+ LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
+ }
+
+ LLFileSystem file(id, asset_type, LLFileSystem::READ);
+ auto size = file.getSize();
+ if (!size)
+ {
+ LL_DEBUGS() << "Zero size material." << LL_ENDL;
+ mat->mFetching = false;
+ mat->unref();
+ return;
+ }
+
+ std::vector<char> buffer;
+ buffer.resize(size);
+ file.read((U8*)&buffer[0], buffer.size());
+
+ LLSD asset;
+
+ // read file into buffer
+ std::istrstream str(&buffer[0], buffer.size());
+
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && asset["version"] == "1.0")
+ {
+ if (asset.has("type") && asset["type"].asString() == "GLTF 2.0")
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ std::string warn_msg, error_msg;
+
+ if (!mat->fromJSON(data, warn_msg, error_msg))
+ {
+ LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;
+ LL_WARNS() << warn_msg << LL_ENDL;
+ LL_WARNS() << error_msg << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+
+ mat->mFetching = false;
+ mat->unref();
+ }, nullptr);
+ }
+
+ return mat;
+ }
+
+ return iter->second;
+}
+
+void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material)
+{
+ mList[id] = material;
+}
+
+void LLGLTFMaterialList::removeMaterial(const LLUUID& id)
+{
+ mList.erase(id);
+}
+
+void LLGLTFMaterialList::flushMaterials()
+{
+ // Similar variant to what textures use
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32
+ //update MIN_UPDATE_COUNT or 5% of materials, whichever is greater
+ U32 update_count = llmax((U32)MIN_UPDATE_COUNT, (U32)mList.size() / 20);
+ update_count = llmin(update_count, (U32)mList.size());
+
+ const F64 MAX_INACTIVE_TIME = 30.f;
+ F64 cur_time = LLTimer::getTotalSeconds();
+
+ // advance iter one past the last key we updated
+ uuid_mat_map_t::iterator iter = mList.find(mLastUpdateKey);
+ if (iter != mList.end()) {
+ ++iter;
+ }
+
+ while (update_count-- > 0)
+ {
+ if (iter == mList.end())
+ {
+ iter = mList.begin();
+ }
+
+ LLPointer<LLFetchedGLTFMaterial> material = iter->second;
+ if (material->getNumRefs() == 2) // this one plus one from the list
+ {
+
+ if (!material->mActive
+ && cur_time > material->mExpectedFlusTime)
+ {
+ iter = mList.erase(iter);
+ }
+ else
+ {
+ if (material->mActive)
+ {
+ material->mExpectedFlusTime = cur_time + MAX_INACTIVE_TIME;
+ material->mActive = false;
+ }
+ ++iter;
+ }
+ }
+ else
+ {
+ material->mActive = true;
+ ++iter;
+ }
+ }
+
+ if (iter != mList.end())
+ {
+ mLastUpdateKey = iter->first;
+ }
+ else
+ {
+ mLastUpdateKey.setNull();
+ }
+}
+
+// static
+void LLGLTFMaterialList::registerCallbacks()
+{
+ gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message);
+}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
new file mode 100644
index 0000000000..ee32dc8825
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.h
@@ -0,0 +1,70 @@
+/**
+ * @file llgltfmateriallist.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llfetchedgltfmaterial.h"
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+
+#include <unordered_map>
+
+class LLFetchedGLTFMaterial;
+
+class LLGLTFMaterialList
+{
+public:
+ LLGLTFMaterialList() {}
+
+
+ LLGLTFMaterial* getMaterial(const LLUUID& id);
+
+ void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);
+ void removeMaterial(const LLUUID& id);
+
+ void flushMaterials();
+
+ static void registerCallbacks();
+
+ // save an override update for later (for example, if an override arrived for an unknown object)
+ void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
+
+ void applyQueuedOverrides(LLViewerObject* obj);
+
+private:
+ typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t;
+ uuid_mat_map_t mList;
+
+ typedef std::vector<LLPointer<LLGLTFMaterial> > override_list_t;
+ typedef std::unordered_map<LLUUID, override_list_t > queued_override_map_t;
+ queued_override_map_t mQueuedOverrides;
+
+ LLUUID mLastUpdateKey;
+};
+
+extern LLGLTFMaterialList gGLTFMaterialList;
+
+
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e7bc2a9268..84a1278767 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
// static
void LLGroupActions::search()
{
- LLFloaterReg::showInstance("search");
+ LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
}
// static
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 62414d3bbb..32af2592d3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -45,7 +45,6 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
-S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@@ -65,21 +64,81 @@ public:
}
};
-static const LLGroupComparator GROUP_COMPARATOR;
+class LLSharedGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ LLSharedGroupComparator() {};
+
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1);
+ std::string name1 = group_item1->getGroupName();
+ bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
+
+ const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2);
+ std::string name2 = group_item2->getGroupName();
+ bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
+ if (item2_shared != item1_shared)
+ {
+ return item1_shared;
+ }
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static LLGroupComparator GROUP_COMPARATOR;
+static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
+
+LLGroupList::Params::Params()
+: for_agent("for_agent", true)
+{
+}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
+ , mForAgent(p.for_agent)
, mDirty(true) // to force initial update
+ , mShowIcons(false)
+ , mShowNone(true)
{
- // Listen for agent group changes.
- gAgent.addListener(this, "new group");
-
- mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// Set default sort order.
- setComparator(&GROUP_COMPARATOR);
+ if (mForAgent)
+ {
+ setComparator(&GROUP_COMPARATOR);
+ }
+ else
+ {
+ // shared groups first
+ setComparator(&SHARED_GROUP_COMPARATOR);
+ }
+
+ if (mForAgent)
+ {
+ enableForAgent(true);
+ }
+}
+
+LLGroupList::~LLGroupList()
+{
+ if (mForAgent) gAgent.removeListener(this);
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+void LLGroupList::enableForAgent(bool show_icons)
+{
+ mForAgent = true;
+
+ mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
+
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
mContextMenuHandle = context_menu->getHandle();
}
-LLGroupList::~LLGroupList()
-{
- gAgent.removeListener(this);
- if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
-}
-
// virtual
void LLGroupList::draw()
{
@@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLToggleableMenu* context_menu = mContextMenuHandle.get();
- if (context_menu && size() > 0)
- {
- context_menu->buildDrawLabels();
- context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, context_menu, x, y);
+ if (mForAgent)
+ {
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
+ if (context_menu && size() > 0)
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
}
return handled;
@@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
// Handle double click only for the selected item in the list, skip clicks on empty space.
if (handled)
{
- if (mDoubleClickSignal)
+ if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
{
(*mDoubleClickSignal)(this, x, y, mask);
}
@@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
- const LLUUID& highlight_id = gAgent.getGroupID();
- S32 count = gAgent.mGroups.size();
- LLUUID id;
- bool have_filter = !mNameFilter.empty();
-
- clear();
-
- for(S32 i = 0; i < count; ++i)
- {
- id = gAgent.mGroups.at(i).mID;
- const LLGroupData& group_data = gAgent.mGroups.at(i);
- if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
- continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
- }
-
- // Sort the list.
- sort();
-
- // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
- // but only if some real groups exists. EXT-4838
- if (!have_filter && count > 0)
- {
- std::string loc_none = LLTrans::getString("GroupsNone");
- addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
- }
-
- selectItemByUUID(highlight_id);
+ if (mForAgent)
+ {
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.size();
+ LLUUID id;
+ bool have_filter = !mNameFilter.empty();
+
+ clear();
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = gAgent.mGroups.at(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.at(i);
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
+ continue;
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
+ }
+
+ // Sort the list.
+ sort();
+
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ // but only if some real groups exists. EXT-4838
+ if (!have_filter && count > 0 && mShowNone)
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
+ }
+
+ selectItemByUUID(highlight_id);
+ }
+ else
+ {
+ clear();
+
+ for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
+ }
+
+ // Sort the list.
+ sort();
+ }
setDirty(false);
onCommit();
@@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
}
}
+void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
+{
+ mGroups = group_list;
+ setDirty(true);
+}
+
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
{
- LLGroupListItem* item = new LLGroupListItem();
+ LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
item->setGroupIconVisible(mShowIcons);
-
+ if (!mShowIcons)
+ {
+ item->setVisibleInProfile(visible_in_profile);
+ }
addItem(item, id, pos);
// setCommentVisible(false);
@@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
return true;
}
+ if (event->desc() == "value_changed")
+ {
+ LLSD data = event->getValue();
+ if (data.has("group_id") && data.has("visible"))
+ {
+ LLUUID group_id = data["group_id"].asUUID();
+ bool visible = data["visible"].asBoolean();
+
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*it);
+ if (item && item->getGroupID() == group_id)
+ {
+ item->setVisibleInProfile(visible);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
return false;
}
@@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
-LLGroupListItem::LLGroupListItem()
+LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
: LLPanel(),
mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
-mGroupID(LLUUID::null)
+mProfileBtn(NULL),
+mVisibilityHideBtn(NULL),
+mVisibilityShowBtn(NULL),
+mGroupID(LLUUID::null),
+mForAgent(for_agent)
{
- buildFromFile( "panel_group_list_item.xml");
-
- // Remember group icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
- if (!sIconWidth)
- {
- sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
- }
+ if (show_icons)
+ {
+ buildFromFile( "panel_group_list_item.xml");
+ }
+ else
+ {
+ buildFromFile( "panel_group_list_item_short.xml");
+ }
}
LLGroupListItem::~LLGroupListItem()
@@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
mInfoBtn = getChild<LLButton>("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
- childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
+ mProfileBtn = getChild<LLButton>("profile_btn");
+ mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+
+ mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
+ }
+ mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn");
+ if (mVisibilityShowBtn)
+ {
+ mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
+ }
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ // Also note that panel_group_list_item and panel_group_list_item_short
+ // have icons of different sizes so we need to figure it per file.
+ mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
return TRUE;
}
@@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
if (mGroupID.notNull()) // don't show the info button for the "none" group
{
mInfoBtn->setVisible(true);
- getChildView("profile_btn")->setVisible( true);
+ mProfileBtn->setVisible(true);
+ if (mForAgent && mVisibilityHideBtn)
+ {
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ }
}
LLPanel::onMouseEnter(x, y, mask);
@@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
- getChildView("profile_btn")->setVisible( false);
+ mProfileBtn->setVisible(false);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(false);
+ mVisibilityShowBtn->setVisible(false);
+ }
LLPanel::onMouseLeave(x, y, mask);
}
@@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
mID = group_id;
mGroupID = group_id;
- setActive(group_id == gAgent.getGroupID());
+
+ if (mForAgent)
+ {
+ // Active group should be bold.
+ setBold(group_id == gAgent.getGroupID());
+ }
+ else
+ {
+ // Groups shared with the agent should be bold
+ setBold(gAgent.isInGroup(group_id, true));
+ }
LLGroupMgr::getInstance()->addObserver(this);
}
@@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
// Move the group name horizontally by icon size + its distance from the group name.
LLRect name_rect = mGroupNameBox->getRect();
- name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
mGroupNameBox->setRect(name_rect);
}
+void LLGroupListItem::setVisibleInProfile(bool visible)
+{
+ mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
+}
+
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupListItem::setActive(bool active)
+void LLGroupListItem::setBold(bool bold)
{
// *BUG: setName() overrides the style params.
- // Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
// is predefined as bold (SansSerifSmallBold, for example)
- new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
mGroupNameStyle.font = new_font;
@@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
+{
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
+ setVisibleInProfile(new_visibility);
+ mVisibilityHideBtn->setVisible(new_visibility);
+ mVisibilityShowBtn->setVisible(!new_visibility);
+ }
+}
+
void LLGroupListItem::changed(LLGroupChange gc)
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
- if(group_data)
- setGroupIconID(group_data->mInsigniaID);
+ if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
+ {
+ setGroupIconID(group_data->mInsigniaID);
+ }
}
//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 171b77fb00..5cbabb712f 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
- Params(){};
+ Optional<bool> for_agent;
+ Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
+ void enableForAgent(bool show_icons);
+
virtual void draw(); // from LLView
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
@@ -63,13 +66,16 @@ public:
void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
+ void setShowNone(bool show_none) { mShowNone = show_none; }
+ void setGroups(const std::map< std::string,LLUUID> group_list);
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool onContextMenuItemClick(const LLSD& userdata);
@@ -80,6 +86,11 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
+
+ bool mForAgent;
+ bool mShowNone;
+ typedef std::map< std::string,LLUUID> group_map_t;
+ group_map_t mGroups;
};
class LLButton;
@@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
- LLGroupListItem();
+ LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@@ -106,19 +117,26 @@ public:
void setGroupIconVisible(bool visible);
virtual void changed(LLGroupChange gc);
+
+ void setVisibleInProfile(bool visible);
private:
- void setActive(bool active);
+ void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
LLGroupIconCtrl* mGroupIcon;
- LLButton* mInfoBtn;
+ LLButton* mInfoBtn;
+ LLButton* mProfileBtn;
+ LLButton* mVisibilityHideBtn;
+ LLButton* mVisibilityShowBtn;
std::string mGroupName;
+ bool mForAgent;
LLStyle::Params mGroupNameStyle;
- static S32 sIconWidth; // icon width + padding
+ S32 mIconWidth;
};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7f65153879..a9e5e55451 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -53,6 +53,7 @@
#include "llviewerregion.h"
#include <boost/regex.hpp>
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
@@ -1859,6 +1860,9 @@ void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
//static
void LLGroupMgr::sendGroupMemberJoin(const LLUUID& group_id)
{
+
+ LLUIUsage::instance().logCommand("Group.Join");
+
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_JoinGroupRequest);
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 6898dce7b1..0f230067bc 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -495,7 +495,7 @@ void LLHUDEffectLookAt::render()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index ecf6d42d69..dfa299528a 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -322,7 +322,7 @@ void LLHUDEffectPointAt::render()
update();
if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 85a878c4a2..38be2b69fd 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -64,7 +64,6 @@ LLHUDIcon::icon_instance_t LLHUDIcon::sIconInstances;
LLHUDIcon::LLHUDIcon(const U8 type) :
LLHUDObject(type),
mImagep(NULL),
- mPickID(0),
mScale(0.1f),
mHidden(FALSE)
{
@@ -76,15 +75,11 @@ LLHUDIcon::~LLHUDIcon()
mImagep = NULL;
}
-void LLHUDIcon::renderIcon(BOOL for_select)
+void LLHUDIcon::render()
{
LLGLSUIDefault texture_state;
LLGLDepthTest gls_depth(GL_TRUE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
- if (for_select)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
if (mHidden)
return;
@@ -116,7 +111,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
mDistance = dist_vec(icon_position, camera->getOrigin());
- F32 alpha_factor = for_select ? 1.f : clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
+ F32 alpha_factor = clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
@@ -150,13 +145,6 @@ void LLHUDIcon::renderIcon(BOOL for_select)
LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
- if (for_select)
- {
- // set color to unique color id for picking
- LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID);
- gGL.color4ubv(coloru.mV);
- }
- else
{
LLColor4 icon_color = LLColor4::white;
icon_color.mV[VALPHA] = alpha_factor;
@@ -198,11 +186,6 @@ void LLHUDIcon::markDead()
LLHUDObject::markDead();
}
-void LLHUDIcon::render()
-{
- renderIcon(FALSE);
-}
-
BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
if (mHidden)
@@ -296,37 +279,6 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
}
//static
-S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size)
-{
- S32 cur_id = start_id;
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- (*icon_it)->mPickID = cur_id;
- cur_id += step_size;
- }
-
- return cur_id;
-}
-
-//static
-LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
-{
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- if (pick_id == (*icon_it)->mPickID)
- {
- return *icon_it;
- }
- }
-
- return NULL;
-}
-
-//static
LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
icon_instance_t::iterator icon_it;
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index e00a985ddc..7f452b5c36 100644
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -56,8 +56,6 @@ public:
void restartLifeTimer() { mLifeTimer.reset(); }
- static S32 generatePickIDs(S32 start_id, S32 step_size);
- static LLHUDIcon* handlePick(S32 pick_id);
static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
static void updateAll();
@@ -75,14 +73,11 @@ protected:
LLHUDIcon(const U8 type);
~LLHUDIcon();
- void renderIcon(BOOL for_select); // common render code
-
private:
LLPointer<LLViewerTexture> mImagep;
LLFrameTimer mAnimTimer;
LLFrameTimer mLifeTimer;
F32 mDistance;
- S32 mPickID;
F32 mScale;
BOOL mHidden;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 952fbf8e4b..e2d63ecc0a 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -228,7 +228,7 @@ void LLHUDNameTag::render()
if (sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText(FALSE);
}
}
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 45fa09e1a1..fe6793ce73 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -267,6 +267,13 @@ void LLHUDObject::updateAll()
// static
void LLHUDObject::renderAll()
{
+ LLGLSUIDefault gls_ui;
+
+ gGL.color4f(1, 1, 1, 1);
+
+ gUIProgram.bind();
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
LLHUDObject *hud_objp;
hud_object_list_t::iterator object_it;
@@ -285,6 +292,7 @@ void LLHUDObject::renderAll()
}
LLVertexBuffer::unbind();
+ gUIProgram.unbind();
}
// static
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7be35ac260..7511dabd5b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -102,7 +102,7 @@ void LLHUDText::render()
if (!mOnHUDAttachment && sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText();
}
}
@@ -330,7 +330,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
- LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
+ // Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b7e0a6a794..4d6ebf9cbb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -69,7 +69,7 @@
#include "message.h"
#include "llviewerregion.h"
#include "llcorehttputil.h"
-
+#include "lluiusage.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -532,7 +532,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
- mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
mStartedAsIMCall(voice),
mIsDNDsend(false),
@@ -544,13 +543,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
{
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
- mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
-
- // check if it was AVALINE call
- if (!mOtherParticipantIsAvatar)
- {
- mSessionType = AVALINE_SESSION;
- }
}
else
{
@@ -651,9 +643,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
switch(mSessionType)
{
- case AVALINE_SESSION:
- // no text notifications
- break;
case P2P_SESSION:
LLAvatarNameCache::get(mOtherParticipantID, &av_name);
other_avatar_name = av_name.getUserName();
@@ -781,6 +770,23 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
message["index"] = (LLSD::Integer)mMsgs.size();
message["is_history"] = is_history;
+ LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL;
+ if (from_id == gAgent.getID())
+ {
+ if (mType == IM_SESSION_GROUP_START)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendGroup");
+ }
+ else if (mType == IM_NOTHING_SPECIAL)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendIM");
+ }
+ else
+ {
+ LLUIUsage::instance().logCommand("Chat.SendOther");
+ }
+ }
+
mMsgs.push_front(message);
if (mSpeakers && from_id.notNull())
@@ -913,11 +919,6 @@ bool LLIMModel::LLIMSession::isGroupChat()
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE));
}
-bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
-{
- return !mOtherParticipantIsAvatar;
-}
-
LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const
{
LLUUID hash = LLUUID::null;
@@ -1795,7 +1796,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
-mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@@ -1826,12 +1826,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
return;
}
-
- if (mSession)
- {
- // store previous session type to process Avaline calls in dialogs
- mPreviousSessionType = mSession->mSessionType;
- }
mSession = session;
@@ -1857,7 +1851,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1893,7 +1886,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = new_state;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1910,8 +1902,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
break;
case LLVoiceChannel::STATE_HUNG_UP:
- // this state is coming before session is changed, so, put it into payload map
- mCallDialogPayload["old_session_type"] = mSession->mSessionType;
+ // this state is coming before session is changed
break;
case LLVoiceChannel::STATE_CONNECTED :
@@ -2031,7 +2022,6 @@ void LLCallDialog::onOpen(const LLSD& key)
void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
{
- // *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them
bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE);
@@ -2052,8 +2042,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
else
{
- avatar_icon->setValue("Avaline_Icon");
- avatar_icon->setToolTip(std::string(""));
+ LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL;
+ group_icon->setValue(session_id);
}
}
@@ -2097,13 +2087,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
- bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger();
-
std::string old_caller_name = mPayload["old_channel_name"].asString();
- if (was_avaline_call)
- {
- old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name);
- }
getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@@ -2116,10 +2100,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
if (!mPayload["disconnected_channel_name"].asString().empty())
{
std::string channel_name = mPayload["disconnected_channel_name"].asString();
- if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger())
- {
- channel_name = LLTextUtil::formatPhoneNumber(channel_name);
- }
getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@@ -2135,16 +2115,11 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
LLUUID session_id = mPayload["session_id"].asUUID();
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (callee_name == "anonymous")
+ if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
}
- else if (!is_avatar)
- {
- callee_name = LLTextUtil::formatPhoneNumber(callee_name);
- }
LLSD callee_id = mPayload["other_user_id"];
// Beautification: Since you know who you called, just show display name
@@ -2344,18 +2319,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString(notify_box_type);
}
- // check to see if this is an Avaline call
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (caller_name == "anonymous")
+ if (caller_name == "anonymous") // obsolete? Likely was part of avaline support
{
caller_name = getString("anonymous");
setCallerName(caller_name, caller_name, call_type);
}
- else if (!is_avatar)
- {
- caller_name = LLTextUtil::formatPhoneNumber(caller_name);
- setCallerName(caller_name, caller_name, call_type);
- }
else
{
// Get the full name information
@@ -2375,7 +2343,7 @@ BOOL LLIncomingCallDialog::postBuild()
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
- // starting notification's timer for P2P and AVALINE invitations
+ // starting notification's timer for P2P invitations
mLifetimeTimer.start();
}
else
@@ -2384,7 +2352,7 @@ BOOL LLIncomingCallDialog::postBuild()
}
//it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call
- //and no IM for avaline
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..fdf9806e2e 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
- AVALINE_SESSION,
NONE_SESSION,
} SType;
@@ -92,12 +91,10 @@ public:
bool isAdHoc();
bool isP2P();
bool isGroupChat();
- bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
- bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
LLUUID generateOutgoingAdHocHash() const;
@@ -136,7 +133,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
- bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@@ -516,7 +512,6 @@ private:
protected:
std::string mPreviousSessionlName;
- LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 479e8f9abf..f382b5985f 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
}
return false;
}
+
+void LLInspect::repositionInspector(const LLSD& data)
+{
+ // Position the inspector relative to the mouse cursor
+ // Similar to how tooltips are positioned
+ // See LLToolTipMgr::createToolTip
+ if (data.has("pos"))
+ {
+ LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
+ }
+ else
+ {
+ LLUI::getInstance()->positionViewNearMouse(this);
+ }
+ applyRectControl();
+}
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..6909aa3f16 100644
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
@@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
+
+ void repositionInspector(const LLSD& data);
protected:
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 10814ac076..b11c440015 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
class LLFetchAvatarData;
@@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// Generate link to avatar profile.
LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
@@ -348,7 +337,7 @@ void LLInspectAvatar::onClickMuteVolume()
LLMuteList* mute_list = LLMuteList::getInstance();
bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
- LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
+ LLMute mute(mAvatarID, mAvatarName.getUserName(), LLMute::AGENT);
if (!is_muted)
{
mute_list->add(mute, LLMute::flagVoiceChat);
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index fa8a53c546..0a30ab9217 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -38,7 +38,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llresmgr.h" // getMonetaryString()
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
#include "lluictrl.h"
#include "llgroupiconctrl.h"
@@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
setGroupID(data["group_id"]);
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index f78a5cc64e..3d13985f08 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -28,16 +28,17 @@
#include "llinspectobject.h"
// Viewer
+#include "llagent.h" // To standup
#include "llfloatersidepanelcontainer.h"
#include "llinspect.h"
#include "llmediaentry.h"
-#include "llnotificationsutil.h" // *TODO: Eliminate, add LLNotificationsUtil wrapper
#include "llselectmgr.h"
#include "llslurl.h"
#include "llviewermenu.h" // handle_object_touch(), handle_buy()
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llviewerobjectlist.h" // to select the requested object
+#include "llvoavatarself.h"
// Linden libraries
#include "llbutton.h" // setLabel(), not virtual!
@@ -49,7 +50,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
-#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@@ -116,6 +116,7 @@ private:
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
LLSafeHandle<LLObjectSelection> mObjectSelection;
+ boost::signals2::connection mSelectionUpdateSlot;
};
LLInspectObject::LLInspectObject(const LLSD& sd)
@@ -141,6 +142,10 @@ LLInspectObject::LLInspectObject(const LLSD& sd)
LLInspectObject::~LLInspectObject()
{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
/*virtual*/
@@ -175,9 +180,12 @@ BOOL LLInspectObject::postBuild(void)
getChild<LLUICtrl>("more_info_btn")->setCommitCallback(
boost::bind(&LLInspectObject::onClickMoreInfo, this));
- // Watch for updates to selection properties off the network
- LLSelectMgr::getInstance()->mUpdateSignal.connect(
- boost::bind(&LLInspectObject::update, this) );
+ if (!mSelectionUpdateSlot.connected())
+ {
+ // Watch for updates to selection properties off the network
+ mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(
+ boost::bind(&LLInspectObject::update, this));
+ }
return TRUE;
}
@@ -197,17 +205,8 @@ void LLInspectObject::onOpen(const LLSD& data)
{
mObjectFace = data["object_face"];
}
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+
+ LLInspect::repositionInspector(data);
// Promote hovered object to a complete selection, which will also force
// a request for selected object data off the network
@@ -635,7 +634,31 @@ void LLInspectObject::onClickTouch()
void LLInspectObject::onClickSit()
{
- handle_object_sit_or_stand();
+ bool is_sitting = false;
+ if (mObjectSelection)
+ {
+ LLSelectNode* node = mObjectSelection->getFirstRootNode();
+ if (node && node->mValid)
+ {
+ LLViewerObject* root_object = node->getObject();
+ if (root_object
+ && isAgentAvatarValid()
+ && gAgentAvatarp->isSitting()
+ && gAgentAvatarp->getRoot() == root_object)
+ {
+ is_sitting = true;
+ }
+ }
+ }
+
+ if (is_sitting)
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ handle_object_sit(mObjectID);
+ }
closeFloater();
}
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index 272c8acbd5..77320510a6 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
// update the inspector with the current object state
update();
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
}
void LLInspectRemoteObject::onClickMap()
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index d0034eff13..68801b0895 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(notification_id);
}
// virtual
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af1..f7789853b8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -785,13 +785,29 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (obj)
{
- items.push_back(std::string("Copy Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Copy Separator"));
+ }
items.push_back(std::string("Copy"));
if (!isItemCopyable())
{
disabled_items.push_back(std::string("Copy"));
}
+ if (isAgentInventory())
+ {
+ items.push_back(std::string("New folder from selected"));
+ items.push_back(std::string("Subfolder Separator"));
+ std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+ uuid_vec_t ids;
+ std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+ if (!is_only_items_selected(ids) && !is_only_cats_selected(ids))
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
+ }
+
if (obj->getIsLinkType())
{
items.push_back(std::string("Find Original"));
@@ -878,7 +894,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
- items.push_back(std::string("Paste Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Paste Separator"));
+ }
addDeleteContextMenuOptions(items, disabled_items);
@@ -1102,7 +1121,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
LLInventoryModel::cat_array_t categories;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
- if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
+ LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
+ if (categories.size() >= max_count
+ || depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}
@@ -1420,6 +1442,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
new_listener = new LLSettingsBridge(inventory, root, uuid, LLSettingsType::fromInventoryFlags(flags));
break;
+ case LLAssetType::AT_MATERIAL:
+ if (inv_type != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
+ }
+ new_listener = new LLMaterialBridge(inventory, root, uuid);
+ break;
+
default:
LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
@@ -3798,7 +3828,20 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_landmarks(item))
{
- dropToFavorites(item);
+ if (LLClipboard::instance().isCutMode())
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ //changeItemParent() implicity calls dirtyFilter
+ changeItemParent(model, viitem, parent_id, FALSE);
+ }
+ }
+ else
+ {
+ dropToFavorites(item);
+ }
}
}
else if (LLClipboard::instance().isCutMode())
@@ -4011,6 +4054,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Settings"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4038,6 +4082,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Script"));
disabled_items.push_back(std::string("New Note"));
disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Material"));
disabled_items.push_back(std::string("New Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
@@ -4092,20 +4137,25 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (!isInboxFolder() // don't allow creation in inbox
&& outfits_id != mUUID)
{
+ bool menu_items_added = false;
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
{
items.push_back(std::string("New Folder"));
+ menu_items_added = true;
}
if (!isMarketplaceListingsFolder())
{
items.push_back(std::string("New Script"));
items.push_back(std::string("New Note"));
items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Material"));
items.push_back(std::string("New Clothes"));
items.push_back(std::string("New Body Parts"));
items.push_back(std::string("New Settings"));
items.push_back(std::string("upload_def"));
+
+ menu_items_added = true;
if (!LLEnvironment::instance().isInventoryEnabled())
{
@@ -4113,6 +4163,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
}
+ if (menu_items_added)
+ {
+ items.push_back(std::string("Create Separator"));
+ }
}
getClipboardEntries(false, items, disabled_items, flags);
}
@@ -4266,7 +4320,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("Conference Chat Folder"));
items.push_back(std::string("IM All Contacts In Folder"));
}
+
+ if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+ {
+ items.push_back(std::string("Ungroup folder items"));
+ }
}
+ else
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
@@ -4378,6 +4441,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
break;
case DAD_LINK:
@@ -6007,6 +6071,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();
@@ -7198,6 +7263,39 @@ bool LLSettingsBridge::canUpdateRegion() const
// +=================================================+
+// | LLMaterialBridge |
+// +=================================================+
+
+void LLMaterialBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+}
+
+void LLMaterialBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LL_DEBUGS() << "LLMaterialBridge::buildContextMenu()" << LL_ENDL;
+
+ if (isMarketplaceListingsFolder())
+ {
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ hide_context_entries(menu, items, disabled_items);
+ }
+ else
+ {
+ LLItemBridge::buildContextMenu(menu, flags);
+ }
+}
+
+
+// +=================================================+
// | LLLinkBridge |
// +=================================================+
// For broken folder links.
@@ -7584,6 +7682,24 @@ protected:
LLSettingsBridgeAction(const LLUUID& id, LLInventoryModel* model) : LLInvFVBridgeAction(id, model) {}
};
+class LLMaterialBridgeAction : public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ void doIt() override
+ {
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("material_editor", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ }
+ LLInvFVBridgeAction::doIt();
+ }
+ ~LLMaterialBridgeAction() = default;
+private:
+ LLMaterialBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {}
+};
+
LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
const LLUUID& uuid,
@@ -7626,6 +7742,9 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
case LLAssetType::AT_SETTINGS:
action = new LLSettingsBridgeAction(uuid, model);
break;
+ case LLAssetType::AT_MATERIAL:
+ action = new LLMaterialBridgeAction(uuid, model);
+ break;
default:
break;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 0b0ef273e1..6c1ddd716b 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -637,6 +637,17 @@ protected:
};
+class LLMaterialBridge : public LLItemBridge
+{
+public:
+ LLMaterialBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid) :
+ LLItemBridge(inventory, root, uuid) {}
+ virtual void openItem();
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction
//
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 707ff2b7b6..f7dc493109 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -1306,6 +1306,18 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
+ if (isFilterObjectTypesWith(LLInventoryType::IT_MATERIAL))
+ {
+ filtered_types += LLTrans::getString("Materials");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ not_filtered_types += LLTrans::getString("Materials");
+ filtered_by_all_types = FALSE;
+ }
+
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
filtered_types += LLTrans::getString("Notecards");
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d239b23e83..27edc8148e 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1868,6 +1868,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
}
}
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(*it);
+ if (inv_item)
+ {
+ change_item_parent(*it, new_cat_uuid);
+ }
+ else
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
+ }
+ }
+ }
+
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (!floater_inventory)
+ {
+ LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+ return;
+ }
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
+ {
+ if (sidepanel_inventory->getActivePanel())
+ {
+ sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES);
+ LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid);
+ if (fv_folder)
+ {
+ fv_folder->setOpen(TRUE);
+ }
+ }
+ }
+}
+
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (!inv_cat)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool is_only_items_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ if (!inv_item)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name)
+{
+ LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+
+ inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids);
+ gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
+
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -2522,6 +2602,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
(new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile();
}
+ else if ("new_folder_from_selected" == action)
+ {
+
+ LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+ const LLUUID& parent_uuid = first_item->getParentUUID();
+ for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLInventoryObject *item = gInventory.getObject(*it);
+ if (!item || item->getParentUUID() != parent_uuid)
+ {
+ LLNotificationsUtil::add("SameFolderRequired");
+ return;
+ }
+ }
+
+ LLSD args;
+ args["DESC"] = LLTrans::getString("New Folder");
+
+ LLNotificationsUtil::add("CreateSubfolder", args, LLSD(),
+ [ids](const LLSD& notification, const LLSD& response)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (opt == 0)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ settings_name = LLTrans::getString("New Folder");
+ }
+ move_items_to_new_subfolder(ids, settings_name);
+ }
+ });
+ }
+ else if ("ungroup_folder_items" == action)
+ {
+ if (selected_uuid_set.size() == 1)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
+ if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ return;
+ }
+ const LLUUID &new_cat_uuid = inv_cat->getParentUUID();
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array);
+ LLInventoryModel::cat_array_t cats = *cat_array;
+ LLInventoryModel::item_array_t items = *item_array;
+
+ for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter)
+ {
+ LLViewerInventoryCategory* cat = *cat_iter;
+ if (cat)
+ {
+ gInventory.changeCategoryParent(cat, new_cat_uuid, false);
+ }
+ }
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter)
+ {
+ LLViewerInventoryItem* item = *item_iter;
+ if(item)
+ {
+ gInventory.changeItemParent(item, new_cat_uuid, false);
+ }
+ }
+ gInventory.removeCategory(inv_cat->getUUID());
+ gInventory.notifyObservers();
+ }
+ }
else
{
std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8915bfa1e0..ba9f157e47 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -93,6 +93,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name);
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
+bool is_only_items_selected(const uuid_vec_t& selected_uuids);
/** Miscellaneous global functions
** **
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 44e493fdf4..e9b0e8404a 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -99,6 +99,8 @@ LLIconDictionary::LLIconDictionary()
addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay"));
addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings"));
+ addEntry(LLInventoryType::ICONNAME_MATERIAL, new IconEntry("Inv_Material"));
+
addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown"));
@@ -177,6 +179,9 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
case LLAssetType::AT_SETTINGS:
idx = assignSettingsIcon(misc_flag);
break;
+ case LLAssetType::AT_MATERIAL:
+ idx = LLInventoryType::ICONNAME_MATERIAL;
+ break;
case LLAssetType::AT_UNKNOWN:
idx = LLInventoryType::ICONNAME_UNKNOWN;
default:
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 12bb609df8..de6a850b57 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -298,31 +298,41 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem
applyXUILayout(icon_params, this);
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
- if (mIconCtrl)
- {
- addChild(mIconCtrl);
- }
- else
+ if (!mIconCtrl)
{
LLIconCtrl::Params icon_params;
icon_params.name = "item_icon";
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
}
+ if (mIconCtrl)
+ {
+ addChild(mIconCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mIconCtrl" << LL_ENDL;
+ }
+
LLTextBox::Params text_params(params.item_name);
applyXUILayout(text_params, this);
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
- if (mTitleCtrl)
+ if (!mTitleCtrl)
{
- addChild(mTitleCtrl);
- }
- else
- {
- LLTextBox::Params text_aprams;
+ LLTextBox::Params text_params;
text_params.name = "item_title";
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
}
+
+ if (mTitleCtrl)
+ {
+ addChild(mTitleCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mTitleCtrl" << LL_ENDL;
+ }
}
class WidgetVisibilityChanger
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c101033a5d..b5853ad9a3 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -135,15 +135,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
///----------------------------------------------------------------------------
/// Class LLInventoryValidationInfo
///----------------------------------------------------------------------------
-LLInventoryValidationInfo::LLInventoryValidationInfo():
- mFatalErrorCount(0),
- mWarningCount(0),
- mLoopCount(0),
- mOrphanedCount(0),
- mInitialized(false),
- mFatalNoRootFolder(false),
- mFatalNoLibraryRootFolder(false),
- mFatalQADebugMode(false)
+LLInventoryValidationInfo::LLInventoryValidationInfo()
{
}
@@ -165,7 +157,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v)
void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
- sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
@@ -173,6 +164,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder;
sd["fatal_qa_debug_mode"] = mFatalQADebugMode;
+
+ sd["warning_count"] = mWarningCount;
+ if (mWarningCount>0)
+ {
+ sd["warnings"] = LLSD::emptyArray();
+ for (auto const& it : mWarnings)
+ {
+ S32 val =LLSD::Integer(it.second);
+ if (val>0)
+ {
+ sd["warnings"][it.first] = val;
+ }
+ }
+ }
if (mMissingRequiredSystemFolders.size()>0)
{
sd["missing_system_folders"] = LLSD::emptyArray();
@@ -342,13 +347,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
-LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
+LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
@@ -358,19 +363,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
- return ANSCESTOR_LOOP;
+ return ANCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
- return ANSCESTOR_OK;
+ return ANCESTOR_OK;
}
// Get the object by id. Returns NULL if not found.
@@ -539,9 +544,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E
LLViewerInventoryCategory* cat = getCategory(*it);
changeCategoryParent(cat, main_id, TRUE);
}
-
+
// Purge the emptied folder
- removeCategory(folder_id);
+ // Note that this might be a system folder, don't validate removability
+ LLViewerInventoryCategory* cat = getCategory(folder_id);
+ if (cat)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull())
+ {
+ changeCategoryParent(cat, trash_id, TRUE);
+ }
+ }
remove_inventory_category(folder_id, NULL);
}
}
@@ -628,6 +642,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType::
cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder"));
break;
}
+ case LLFolderType::FT_MATERIAL:
+ {
+ cat_id = LLUUID(gSavedPerAccountSettings.getString("PBRUploadFolder"));
+ break;
+ }
default:
break;
}
@@ -2822,6 +2841,7 @@ void LLInventoryModel::createCommonSystemCategories()
gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, true); // folder should exist before user tries to 'landmark this'
gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS, true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL, true); // probably should be server created
gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, true);
}
@@ -3129,7 +3149,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
gInventory.accountForUpdate(update);
}
- U32 changes = 0x0;
if (account)
{
mask |= LLInventoryObserver::CREATE;
@@ -3137,7 +3156,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
//as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it, mask);
+ gInventory.updateItem(*it, mask);
}
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@@ -3896,9 +3915,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatal_errs = 0;
- S32 warnings = 0;
- S32 loops = 0;
- S32 orphaned = 0;
+ S32 warning_count= 0;
+ S32 loop_count = 0;
+ S32 orphaned_count = 0;
if (getRootFolderID().isNull())
{
@@ -3919,7 +3938,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
- warnings++;
+
+ validation_info->mWarnings["category_map_size"]++;
+ warning_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@@ -3938,32 +3959,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cat)
{
LL_WARNS("Inventory") << "null cat" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_cat"]++;
+ warning_count++;
continue;
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
- EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+ EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
- case ANSCESTOR_MISSING:
- orphaned++;
+ case ANCESTOR_MISSING:
+ orphaned_count++;
break;
- case ANSCESTOR_LOOP:
- loops++;
+ case ANCESTOR_LOOP:
+ loop_count++;
break;
- case ANSCESTOR_OK:
+ case ANCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["unknown_ancestor_status"]++;
+ warning_count++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["cat_id_index_mismatch"]++;
+ warning_count++;
}
if (cat->getParentUUID().isNull())
@@ -3973,7 +3997,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("
<< getRootFolderID() << ") or library root ("
<< getLibraryRootFolderID() << ")" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_parent"]++;
+ warning_count++;
}
}
cat_array_t* cats;
@@ -3982,7 +4007,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cats || !items)
{
LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["direct_descendents"]++;
+ warning_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@@ -4000,7 +4026,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " cached " << cat->getDescendentCount()
<< " expected " << cats->size() << "+" << items->size()
<< "=" << cats->size() +items->size() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["invalid_descendent_count"]++;
+ warning_count++;
}
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@@ -4024,7 +4051,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!item)
{
LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_item_at_index"]++;
+ warning_count++;
continue;
}
@@ -4035,7 +4063,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "
<< item->getParentUUID() << " expected " << cat_id
<< LL_ENDL;
- warnings++;
+ validation_info->mWarnings["wrong_parent_for_item"]++;
+ warning_count++;
}
@@ -4045,7 +4074,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " found as child of "
<< cat_id << " but not in top level mItemMap" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_not_in_top_map"]++;
+ warning_count++;
}
else
{
@@ -4059,11 +4089,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
- EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
- if (found != ANSCESTOR_OK)
+ EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
+ if (found != ANCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_found"]++;
+ warning_count++;
}
else
{
@@ -4074,7 +4105,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
+ warning_count++;
}
}
}
@@ -4090,7 +4122,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4108,7 +4140,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
}
@@ -4117,7 +4149,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
- if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
+ if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@@ -4150,14 +4182,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (item->getUUID() != item_id)
{
LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_id_mismatch"]++;
+ warning_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4168,7 +4201,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4185,7 +4218,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
@@ -4203,18 +4236,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
if (target_item && target_item->getIsLinkType())
{
@@ -4286,23 +4319,30 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
- fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
+ fatal_errs++;
}
else
{
// Can create, and will when needed.
- warnings++;
+ // (Not sure this is really a warning, but worth logging)
+ validation_info->mWarnings["missing_system_folder_can_create"]++;
+ warning_count++;
}
}
else if (count_under_root > 1)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL;
validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
- if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
+ if (!is_automatic
+ && folder_type != LLFolderType::FT_SETTINGS
+ // FT_MATERIAL might need to be automatic like the rest of upload folders
+ && folder_type != LLFolderType::FT_MATERIAL
+ )
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
+ validation_info->mFatalSystemDuplicate++;
fatal_errs++;
}
else
@@ -4310,13 +4350,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++;
+ warning_count++;
}
}
if (count_elsewhere > 0)
{
LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
+ warning_count++;
}
}
}
@@ -4338,12 +4380,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatal_errs == 0);
- LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
+ LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatal_errs;
- validation_info->mWarningCount = warnings;
- validation_info->mLoopCount = loops;
- validation_info->mOrphanedCount = orphaned;
+ validation_info->mWarningCount = warning_count;
+ validation_info->mLoopCount = loop_count;
+ validation_info->mOrphanedCount = orphaned_count;
return validation_info;
}
@@ -4548,12 +4590,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
}
// as above, this loop never seems to loop more than once per call
- U32 changes(0U);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it);
+ gInventory.updateItem(*it);
}
- // *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 85343cf95c..cb960d8185 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -65,15 +65,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
+ bool mInitialized{false};
+ S32 mWarningCount{0};
+ std::map<std::string,U32> mWarnings;
+
+ S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves
+ S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders
+
+ S32 mFatalErrorCount{0};
+ bool mFatalNoRootFolder{false};
+ S32 mFatalSystemDuplicate{0};
+ bool mFatalNoLibraryRootFolder{false};
+ bool mFatalQADebugMode{false};
- S32 mFatalErrorCount;
- S32 mWarningCount;
- S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
- S32 mOrphanedCount; // Missing or orphaned items, links and folders
- bool mInitialized;
- bool mFatalNoRootFolder;
- bool mFatalNoLibraryRootFolder;
- bool mFatalQADebugMode;
std::set<LLFolderType::EType> mMissingRequiredSystemFolders;
std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;
};
@@ -286,13 +290,13 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
- enum EAnscestorResult{
- ANSCESTOR_OK = 0,
- ANSCESTOR_MISSING = 1,
- ANSCESTOR_LOOP = 2,
+ enum EAncestorResult{
+ ANCESTOR_OK = 0,
+ ANCESTOR_MISSING = 1,
+ ANCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
- EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+ EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 6b102c7500..bc035fc2f6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1612,6 +1612,10 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
{
gSavedPerAccountSettings.setString("AnimationUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
}
+ else if (param == "pbr_material")
+ {
+ gSavedPerAccountSettings.setString("PBRUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
+ }
}
void LLInventoryPanel::purgeSelectedItems()
@@ -2010,7 +2014,43 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
{
- mAssetType = LLAssetType::lookup(p.filter_asset_type.getValue());
+ // Init asset types
+ std::string types = p.filter_asset_types.getValue();
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|");
+ tokenizer tokens(types, sep);
+ tokenizer::iterator token_iter = tokens.begin();
+
+ memset(mAssetTypes, 0, LLAssetType::AT_COUNT * sizeof(bool));
+ while (token_iter != tokens.end())
+ {
+ const std::string& token_str = *token_iter;
+ LLAssetType::EType asset_type = LLAssetType::lookup(token_str);
+ if (asset_type > LLAssetType::AT_NONE && asset_type < LLAssetType::AT_COUNT)
+ {
+ mAssetTypes[asset_type] = true;
+ }
+ ++token_iter;
+ }
+
+ // Init drag types
+ memset(mDragTypes, 0, EDragAndDropType::DAD_COUNT * sizeof(bool));
+ for (S32 i = 0; i < LLAssetType::AT_COUNT; i++)
+ {
+ if (mAssetTypes[i])
+ {
+ EDragAndDropType drag_type = LLViewerAssetType::lookupDragAndDropType((LLAssetType::EType)i);
+ if (drag_type != DAD_NONE)
+ {
+ mDragTypes[drag_type] = true;
+ }
+ }
+ }
+ // Always show AT_CATEGORY, but it shouldn't get into mDragTypes
+ mAssetTypes[LLAssetType::AT_CATEGORY] = true;
+
+ // Init the panel
LLInventoryPanel::initFromParams(p);
U64 filter_cats = getFilter().getFilterCategoryTypes();
filter_cats &= ~(1ULL << LLFolderType::FT_MARKETPLACE_LISTINGS);
@@ -2028,10 +2068,9 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
if (mAcceptsDragAndDrop)
{
- EDragAndDropType allow_type = LLViewerAssetType::lookupDragAndDropType(mAssetType);
// Don't allow DAD_CATEGORY here since it can contain other items besides required assets
// We should see everything we drop!
- if (allow_type == cargo_type)
+ if (mDragTypes[cargo_type])
{
result = LLInventoryPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
@@ -2047,8 +2086,14 @@ bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInvento
{
return false;
}
+ LLAssetType::EType asset_type = objectp->getType();
+
+ if (asset_type < 0 || asset_type >= LLAssetType::AT_COUNT)
+ {
+ return false;
+ }
- if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
+ if (!mAssetTypes[asset_type])
{
return false;
}
@@ -2064,11 +2109,16 @@ void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, cons
return;
}
- if (model_item
- && model_item->getType() != mAssetType
- && model_item->getType() != LLAssetType::AT_CATEGORY)
+ if (model_item)
{
- return;
+ LLAssetType::EType asset_type = model_item->getType();
+
+ if (asset_type < 0
+ || asset_type >= LLAssetType::AT_COUNT
+ || !mAssetTypes[asset_type])
+ {
+ return;
+ }
}
LLInventoryPanel::itemChanged(id, mask, model_item);
@@ -2104,6 +2154,7 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
declare(LLFolderType::lookup(LLFolderType::FT_SETTINGS) , LLFolderType::FT_SETTINGS);
+ declare(LLFolderType::lookup(LLFolderType::FT_MATERIAL) , LLFolderType::FT_MATERIAL);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_VERSION), LLFolderType::FT_MARKETPLACE_VERSION);
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 552c61b915..d5219a22e7 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -393,9 +393,9 @@ public:
struct Params
: public LLInitParam::Block<Params, LLInventoryPanel::Params>
{
- Mandatory<std::string> filter_asset_type;
+ Mandatory<std::string> filter_asset_types;
- Params() : filter_asset_type("filter_asset_type") {}
+ Params() : filter_asset_types("filter_asset_types") {}
};
void initFromParams(const Params& p);
@@ -416,7 +416,8 @@ protected:
/*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
private:
- LLAssetType::EType mAssetType;
+ bool mAssetTypes[LLAssetType::AT_COUNT];
+ bool mDragTypes[EDragAndDropType::DAD_COUNT];
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index 1364067949..ce4ec668f1 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
return;
}
- const BOOL hide_clip_plane = TRUE;
LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
@@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
render_fog_color = sky_fog_color;
- F32 fog_density = 0.f;
fog_distance = mFogRatio * distance;
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
mGLFogCol = fog;
-
- if (hide_clip_plane)
- {
- // For now, set the density to extend to the cull distance.
- const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
- fog_density = f_log/fog_distance;
- }
- else
- {
- const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
- fog_density = (f_log)/fog_distance;
- }
}
else
{
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
F32 depth = water_height - camera_height;
-
- // get the water param manager variables
- float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
LLColor4 water_fog_color(pwater->getWaterFogColor());
@@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the gl fog color
mGLFogCol = fogCol;
-
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
}
mFogColor = sky_fog_color;
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 5a17332fde..257208470e 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -47,7 +47,6 @@
/* misc headers */
#include "llscrolllistctrl.h"
-#include "llfilepicker.h"
#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
@@ -62,6 +61,7 @@
#include "pipeline.h"
#include "llmaterialmgr.h"
#include "llimagedimensionsinfo.h"
+#include "llinventoryicon.h"
#include "llviewercontrol.h"
#include "lltrans.h"
#include "llviewerdisplay.h"
@@ -919,51 +919,49 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
-bool LLLocalBitmapMgr::addUnit()
+bool LLLocalBitmapMgr::addUnit(const std::vector<std::string>& filenames)
{
- bool add_successful = false;
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
- {
- mTimer.stopTimer();
+ bool add_successful = false;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty() && addUnit(*iter).notNull())
+ {
+ add_successful = true;
+ }
+ iter++;
+ }
+ return add_successful;
+}
- std::string filename = picker.getFirstFile();
- while(!filename.empty())
- {
- if(!checkTextureDimensions(filename))
- {
- filename = picker.getNextFile();
- continue;
- }
+LLUUID LLLocalBitmapMgr::addUnit(const std::string& filename)
+{
+ if (!checkTextureDimensions(filename))
+ {
+ return LLUUID::null;
+ }
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
- if (unit->getValid())
- {
- mBitmapList.push_back(unit);
- add_successful = true;
- }
- else
- {
- LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
- << "Filename: " << filename << LL_ENDL;
-
- LLSD notif_args;
- notif_args["FNAME"] = filename;
- LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
+ if (unit->getValid())
+ {
+ mBitmapList.push_back(unit);
+ return unit->getTrackingID();
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
- delete unit;
- unit = NULL;
- }
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
- filename = picker.getNextFile();
- }
-
- mTimer.startTimer();
- }
+ delete unit;
+ unit = NULL;
+ }
- return add_successful;
+ return LLUUID::null;
}
bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
@@ -1071,7 +1069,9 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
{
if (ctrl)
{
- ctrl->clearRows();
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_TEXTURE,
+ LLInventoryType::IT_NONE);
if (!mBitmapList.empty())
{
@@ -1079,13 +1079,19 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
iter != mBitmapList.end(); iter++)
{
LLSD element;
- element["columns"][0]["column"] = "unit_name";
- element["columns"][0]["type"] = "text";
- element["columns"][0]["value"] = (*iter)->getShortName();
- element["columns"][1]["column"] = "unit_id_HIDDEN";
- element["columns"][1]["type"] = "text";
- element["columns"][1]["value"] = (*iter)->getTrackingID();
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_TEXTURE;
+ element["value"] = data;
ctrl->addElement(element);
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index d5ee7efdc6..bb026ed3aa 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -115,14 +115,15 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
LLSINGLETON(LLLocalBitmapMgr);
~LLLocalBitmapMgr();
public:
- bool addUnit();
+ bool addUnit(const std::vector<std::string>& filenames);
+ LLUUID addUnit(const std::string& filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
LLUUID getWorldID(LLUUID tracking_id);
bool isLocal(LLUUID world_id);
std::string getFilename(LLUUID tracking_id);
-
+
void feedScrollList(LLScrollListCtrl* ctrl);
void doUpdates();
void setNeedsRebake();
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
new file mode 100644
index 0000000000..f194226fa5
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -0,0 +1,628 @@
+/**
+ * @file lllocalrendermaterials.cpp
+ * @brief Local GLTF materials source
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/* precompiled headers */
+#include "llviewerprecompiledheaders.h"
+
+/* own header */
+#include "lllocalgltfmaterials.h"
+
+/* boost: will not compile unless equivalent is undef'd, beware. */
+#include "fix_macros.h"
+#include <boost/filesystem.hpp>
+
+/* time headers */
+#include <time.h>
+#include <ctime>
+
+/* misc headers */
+#include "llgltfmateriallist.h"
+#include "llimage.h"
+#include "llinventoryicon.h"
+#include "llmaterialmgr.h"
+#include "llnotificationsutil.h"
+#include "llscrolllistctrl.h"
+#include "lltinygltfhelper.h"
+#include "llviewertexture.h"
+#include "tinygltf/tiny_gltf.h"
+
+/*=======================================*/
+/* Formal declarations, constants, etc. */
+/*=======================================*/
+
+static const F32 LL_LOCAL_TIMER_HEARTBEAT = 3.0;
+static const S32 LL_LOCAL_UPDATE_RETRIES = 5;
+
+/*=======================================*/
+/* LLLocalGLTFMaterial: unit class */
+/*=======================================*/
+LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename, S32 index)
+ : mFilename(filename)
+ , mShortName(gDirUtilp->getBaseFileName(filename, true))
+ , mValid(false)
+ , mLastModified()
+ , mLinkStatus(LS_ON)
+ , mUpdateRetries(LL_LOCAL_UPDATE_RETRIES)
+ , mMaterialIndex(index)
+{
+ mTrackingID.generate();
+
+ /* extension */
+ std::string temp_exten = gDirUtilp->getExtension(mFilename);
+
+ if (temp_exten == "gltf")
+ {
+ mExtension = ET_MATERIAL_GLTF;
+ }
+ else if (temp_exten == "glb")
+ {
+ mExtension = ET_MATERIAL_GLB;
+ }
+ else
+ {
+ LL_WARNS() << "File of no valid extension given, local material creation aborted." << "\n"
+ << "Filename: " << mFilename << LL_ENDL;
+ return; // no valid extension.
+ }
+
+ /* next phase of unit creation is nearly the same as an update cycle.
+ we're running updateSelf as a special case with the optional UT_FIRSTUSE
+ which omits the parts associated with removing the outdated texture */
+ mValid = updateSelf();
+}
+
+LLLocalGLTFMaterial::~LLLocalGLTFMaterial()
+{
+ // delete self from material list
+ gGLTFMaterialList.removeMaterial(mWorldID);
+}
+
+/* accessors */
+std::string LLLocalGLTFMaterial::getFilename()
+{
+ return mFilename;
+}
+
+std::string LLLocalGLTFMaterial::getShortName()
+{
+ return mShortName;
+}
+
+LLUUID LLLocalGLTFMaterial::getTrackingID()
+{
+ return mTrackingID;
+}
+
+LLUUID LLLocalGLTFMaterial::getWorldID()
+{
+ return mWorldID;
+}
+
+S32 LLLocalGLTFMaterial::getIndexInFile()
+{
+ return mMaterialIndex;
+}
+
+bool LLLocalGLTFMaterial::getValid()
+{
+ return mValid;
+}
+
+/* update functions */
+bool LLLocalGLTFMaterial::updateSelf()
+{
+ bool updated = false;
+
+ if (mLinkStatus == LS_ON)
+ {
+ // verifying that the file exists
+ if (gDirUtilp->fileExists(mFilename))
+ {
+ // verifying that the file has indeed been modified
+
+#ifndef LL_WINDOWS
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+#else
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename)));
+#endif
+ LLSD new_last_modified = asctime(localtime(&temp_time));
+
+ if (mLastModified.asString() != new_last_modified.asString())
+ {
+ if (loadMaterial())
+ {
+ // decode is successful, we can safely proceed.
+ if (mWorldID.isNull())
+ {
+ mWorldID.generate();
+ }
+ mLastModified = new_last_modified;
+
+ // addMaterial will replace material witha a new
+ // pointer if value already exists but we are
+ // reusing existing pointer, so it should add only.
+ gGLTFMaterialList.addMaterial(mWorldID, mGLTFMaterial);
+
+ mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
+ updated = true;
+ }
+
+ // if decoding failed, we get here and it will attempt to decode it in the next cycles
+ // until mUpdateRetries runs out. this is done because some software lock the material while writing to it
+ else
+ {
+ if (mUpdateRetries)
+ {
+ mUpdateRetries--;
+ }
+ else
+ {
+ LL_WARNS() << "During the update process the following file was found" << "\n"
+ << "but could not be opened or decoded for " << LL_LOCAL_UPDATE_RETRIES << " attempts." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ notif_args["NRETRIES"] = LL_LOCAL_UPDATE_RETRIES;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFailedFinal", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+ }
+
+ } // end if file exists
+
+ else
+ {
+ LL_WARNS() << "During the update process, the following file was not found." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFileNotFound", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return updated;
+}
+
+bool LLLocalGLTFMaterial::loadMaterial()
+{
+ bool decode_successful = false;
+
+ if (mWorldID.notNull())
+ {
+ // We should already have it, but update mGLTFMaterial just in case
+ // will create a new one if material doesn't exist yet
+ mGLTFMaterial = (LLFetchedGLTFMaterial*)gGLTFMaterialList.getMaterial(mWorldID);
+ }
+ else
+ {
+ mGLTFMaterial = new LLFetchedGLTFMaterial();
+ }
+
+ switch (mExtension)
+ {
+ case ET_MATERIAL_GLTF:
+ case ET_MATERIAL_GLB:
+ {
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ std::string filename_lc = mFilename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+ else
+ { // file is ascii
+ decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+
+ if (!decode_successful)
+ {
+ LL_WARNS() << "Cannot load Material, error: " << error_msg
+ << ", warning:" << warn_msg
+ << " file: " << mFilename
+ << LL_ENDL;
+ break;
+ }
+
+ if (model_in.materials.size() <= mMaterialIndex)
+ {
+ // materials are missing
+ LL_WARNS() << "Cannot load Material, Material " << mMaterialIndex << " is missing, " << mFilename << LL_ENDL;
+ decode_successful = false;
+ break;
+ }
+
+ // sets everything, but textures will have inaccurate ids
+ mGLTFMaterial->setFromModel(model_in, mMaterialIndex);
+
+ std::string folder = gDirUtilp->getDirName(filename_lc);
+ tinygltf::Material material_in = model_in.materials[mMaterialIndex];
+
+ if (!material_in.name.empty())
+ {
+ mShortName = gDirUtilp->getBaseFileName(filename_lc, true) + " (" + material_in.name + ")";
+ }
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index);
+ }
+
+ // todo: pass it into local bitmaps?
+ LLTinyGLTFHelper::initFetchedTextures(material_in,
+ base_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorFetched, mNormalFetched, mMRFetched, mEmissiveFetched);
+
+ if (mBaseColorFetched)
+ {
+ mBaseColorFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mBaseColorId = mBaseColorFetched->getID();
+ mGLTFMaterial->mBaseColorTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mBaseColorId = LLUUID::null;
+ mGLTFMaterial->mBaseColorTexture = nullptr;
+ }
+
+ if (mNormalFetched)
+ {
+ mNormalFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mNormalId = mNormalFetched->getID();
+ mGLTFMaterial->mNormalTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mNormalId = LLUUID::null;
+ mGLTFMaterial->mNormalTexture = nullptr;
+ }
+
+ if (mMRFetched)
+ {
+ mMRFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mMetallicRoughnessId = mMRFetched->getID();
+ mGLTFMaterial->mMetallicRoughnessTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mMetallicRoughnessId = LLUUID::null;
+ mGLTFMaterial->mMetallicRoughnessTexture = nullptr;
+ }
+
+ if (mEmissiveFetched)
+ {
+ mEmissiveFetched->addTextureStats(64.f * 64.f, TRUE);
+ mGLTFMaterial->mEmissiveId = mEmissiveFetched->getID();
+ mGLTFMaterial->mEmissiveTexture = mBaseColorFetched;
+ }
+ else
+ {
+ mGLTFMaterial->mEmissiveId = LLUUID::null;
+ mGLTFMaterial->mEmissiveTexture = nullptr;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // separating this into -several- LL_WARNS() calls because in the extremely unlikely case that this happens
+ // accessing mFilename and any other object properties might very well crash the viewer.
+ // getting here should be impossible, or there's been a pretty serious bug.
+
+ LL_WARNS() << "During a decode attempt, the following local material had no properly assigned extension." << LL_ENDL;
+ LL_WARNS() << "Filename: " << mFilename << LL_ENDL;
+ LL_WARNS() << "Disabling further update attempts for this file." << LL_ENDL;
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return decode_successful;
+}
+
+
+/*=======================================*/
+/* LLLocalGLTFMaterialTimer: timer class */
+/*=======================================*/
+LLLocalGLTFMaterialTimer::LLLocalGLTFMaterialTimer() : LLEventTimer(LL_LOCAL_TIMER_HEARTBEAT)
+{
+}
+
+LLLocalGLTFMaterialTimer::~LLLocalGLTFMaterialTimer()
+{
+}
+
+void LLLocalGLTFMaterialTimer::startTimer()
+{
+ mEventTimer.start();
+}
+
+void LLLocalGLTFMaterialTimer::stopTimer()
+{
+ mEventTimer.stop();
+}
+
+bool LLLocalGLTFMaterialTimer::isRunning()
+{
+ return mEventTimer.getStarted();
+}
+
+BOOL LLLocalGLTFMaterialTimer::tick()
+{
+ // todo: do on idle? No point in timer
+ LLLocalGLTFMaterialMgr::getInstance()->doUpdates();
+ return FALSE;
+}
+
+/*=======================================*/
+/* LLLocalGLTFMaterialMgr: manager class */
+/*=======================================*/
+LLLocalGLTFMaterialMgr::LLLocalGLTFMaterialMgr()
+{
+}
+
+LLLocalGLTFMaterialMgr::~LLLocalGLTFMaterialMgr()
+{
+ std::for_each(mMaterialList.begin(), mMaterialList.end(), DeletePointer());
+ mMaterialList.clear();
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)
+{
+ S32 add_count = 0;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ add_count += addUnit(*iter);
+ }
+ iter++;
+ }
+ return add_count;
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
+{
+ std::string exten = gDirUtilp->getExtension(filename);
+ S32 materials_in_file = 0;
+
+ if (exten == "gltf" || exten == "glb")
+ {
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ bool decode_successful = false;
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+ else
+ { // file is ascii
+ decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+
+ if (!decode_successful)
+ {
+ LL_WARNS() << "Cannot load, error: Failed to decode" << error_msg
+ << ", warning:" << warn_msg
+ << " file: " << filename
+ << LL_ENDL;
+ return 0;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LL_WARNS() << "Cannot load. File has no materials " << filename << LL_ENDL;
+ return 0;
+ }
+ materials_in_file = model_in.materials.size();
+ }
+
+ S32 loaded_materials = 0;
+ for (S32 i = 0; i < materials_in_file; i++)
+ {
+ // Todo: this is rather inefficient, files will be spammed with
+ // separate loads and date checks, find a way to improve this.
+ // May be doUpdates() should be checking individual files.
+ LLLocalGLTFMaterial* unit = new LLLocalGLTFMaterial(filename, i);
+
+ if (unit->getValid())
+ {
+ mMaterialList.push_back(unit);
+ loaded_materials++;
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalGLTFVerifyFail", notif_args);
+
+ delete unit;
+ unit = NULL;
+ }
+ }
+
+ return loaded_materials;
+}
+
+void LLLocalGLTFMaterialMgr::delUnit(LLUUID tracking_id)
+{
+ if (!mMaterialList.empty())
+ {
+ std::vector<LLLocalGLTFMaterial*> to_delete;
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ { /* finding which ones we want deleted and making a separate list */
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ to_delete.push_back(unit);
+ }
+ }
+
+ for (std::vector<LLLocalGLTFMaterial*>::iterator del_iter = to_delete.begin();
+ del_iter != to_delete.end(); del_iter++)
+ { /* iterating over a temporary list, hence preserving the iterator validity while deleting. */
+ LLLocalGLTFMaterial* unit = *del_iter;
+ mMaterialList.remove(unit);
+ delete unit;
+ unit = NULL;
+ }
+ }
+}
+
+LLUUID LLLocalGLTFMaterialMgr::getWorldID(LLUUID tracking_id)
+{
+ LLUUID world_id = LLUUID::null;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ world_id = unit->getWorldID();
+ }
+ }
+
+ return world_id;
+}
+
+bool LLLocalGLTFMaterialMgr::isLocal(const LLUUID world_id)
+{
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getWorldID() == world_id)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLLocalGLTFMaterialMgr::getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index)
+{
+ filename = "";
+ index = 0;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ filename = unit->getFilename();
+ index = unit->getIndexInFile();
+ }
+ }
+}
+
+// probably shouldn't be here, but at the moment this mirrors lllocalbitmaps
+void LLLocalGLTFMaterialMgr::feedScrollList(LLScrollListCtrl* ctrl)
+{
+ if (ctrl)
+ {
+ if (!mMaterialList.empty())
+ {
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_NONE);
+
+ for (local_list_iter iter = mMaterialList.begin();
+ iter != mMaterialList.end(); iter++)
+ {
+ LLSD element;
+
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_MATERIAL;
+ element["value"] = data;
+
+ ctrl->addElement(element);
+ }
+ }
+ }
+
+}
+
+void LLLocalGLTFMaterialMgr::doUpdates()
+{
+ // preventing theoretical overlap in cases with huge number of loaded images.
+ mTimer.stopTimer();
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ (*iter)->updateSelf();
+ }
+
+ mTimer.startTimer();
+}
+
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
new file mode 100644
index 0000000000..097f2ea30a
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -0,0 +1,129 @@
+/**
+ * @file lllocalrendermaterials.h
+ * @brief Local GLTF materials header
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LOCALGLTFMATERIALS_H
+#define LL_LOCALGLTFMATERIALS_H
+
+#include "lleventtimer.h"
+#include "llpointer.h"
+
+class LLScrollListCtrl;
+class LLGLTFMaterial;
+class LLViewerObject;
+class LLViewerFetchedTexture;
+class LLFetchedGLTFMaterial;
+
+class LLLocalGLTFMaterial
+{
+public: /* main */
+ LLLocalGLTFMaterial(std::string filename, S32 index);
+ ~LLLocalGLTFMaterial();
+
+public: /* accessors */
+ std::string getFilename();
+ std::string getShortName();
+ LLUUID getTrackingID();
+ LLUUID getWorldID();
+ S32 getIndexInFile();
+ bool getValid();
+
+public:
+ bool updateSelf();
+
+private:
+ bool loadMaterial();
+
+private: /* private enums */
+ enum ELinkStatus
+ {
+ LS_ON,
+ LS_BROKEN,
+ };
+
+ enum EExtension
+ {
+ ET_MATERIAL_GLTF,
+ ET_MATERIAL_GLB,
+ };
+
+private: /* members */
+ std::string mFilename;
+ std::string mShortName;
+ LLUUID mTrackingID;
+ LLUUID mWorldID;
+ bool mValid;
+ LLSD mLastModified;
+ EExtension mExtension;
+ ELinkStatus mLinkStatus;
+ S32 mUpdateRetries;
+ S32 mMaterialIndex; // Single file can have more than one
+
+ // Maintain textures and material pointers to
+ // make sure they won't be deleted in any way
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+ LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
+ LLPointer<LLViewerFetchedTexture> mNormalFetched;
+ LLPointer<LLViewerFetchedTexture> mMRFetched;
+ LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
+};
+
+class LLLocalGLTFMaterialTimer : public LLEventTimer
+{
+public:
+ LLLocalGLTFMaterialTimer();
+ ~LLLocalGLTFMaterialTimer();
+
+public:
+ void startTimer();
+ void stopTimer();
+ bool isRunning();
+ BOOL tick();
+};
+
+class LLLocalGLTFMaterialMgr : public LLSingleton<LLLocalGLTFMaterialMgr>
+{
+ LLSINGLETON(LLLocalGLTFMaterialMgr);
+ ~LLLocalGLTFMaterialMgr();
+public:
+ S32 addUnit(const std::vector<std::string>& filenames);
+ S32 addUnit(const std::string& filename); // file can hold multiple materials
+ void delUnit(LLUUID tracking_id);
+
+ LLUUID getWorldID(LLUUID tracking_id);
+ bool isLocal(LLUUID world_id);
+ void getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index);
+
+ void feedScrollList(LLScrollListCtrl* ctrl);
+ void doUpdates();
+
+private:
+ std::list<LLLocalGLTFMaterial*> mMaterialList;
+ LLLocalGLTFMaterialTimer mTimer;
+ typedef std::list<LLLocalGLTFMaterial*>::iterator local_list_iter;
+};
+
+#endif // LL_LOCALGLTFMATERIALS_H
+
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 79dbe17982..af2a9f6afd 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
+ bool isNavMeshDirty() { return mIsNavMeshDirty; }
+
private:
enum EParcelIcon
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index a3d0eb5796..82ecfbd4dc 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -280,7 +280,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
mRequestData["options"] = requested_options;
mRequestData["http_params"] = http_params;
#if LL_RELEASE_FOR_DOWNLOAD
- mRequestData["wait_for_updater"] = !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !LLAppViewer::instance()->isUpdaterMissing();
+ mRequestData["wait_for_updater"] = LLAppViewer::instance()->waitForUpdater();
#else
mRequestData["wait_for_updater"] = false;
#endif
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d85a846f4d..6b9543d433 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -277,7 +277,7 @@ void LLManipRotate::render()
LLGLEnable cull_face(GL_CULL_FACE);
LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
// First pass: centers. Second pass: sides.
for( S32 i=0; i<2; i++ )
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index e74fd1241b..c15f1da26b 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -757,7 +757,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.pushMatrix();
{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 0b2a1ef389..b9e68bd6a9 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1063,7 +1063,7 @@ void LLManipTranslate::render()
renderGuidelines();
}
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderTranslationHandles();
renderSnapGuides();
}
@@ -1529,7 +1529,7 @@ void LLManipTranslate::renderSnapGuides()
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
{
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
@@ -1628,6 +1628,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
+#if 0 // DEPRECATED
if (!gSavedSettings.getBOOL("GridCrossSections"))
{
return;
@@ -1651,13 +1652,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
{
- glStencilMask(stencil_mask);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
+ //glStencilMask(stencil_mask); //deprecated
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
LLGLEnable cull_face(GL_CULL_FACE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
- glStencilFunc(GL_ALWAYS, 0, stencil_mask);
+ //glStencilFunc(GL_ALWAYS, 0, stencil_mask);
gGL.setColorMask(false, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1690,14 +1691,14 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
//stencil in volumes
- glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+ //glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glCullFace(GL_FRONT);
for (U32 i = 0; i < num_types; i++)
{
gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
}
- glStencilOp(GL_DECR, GL_DECR, GL_DECR);
+ //glStencilOp(GL_DECR, GL_DECR, GL_DECR);
glCullFace(GL_BACK);
for (U32 i = 0; i < num_types; i++)
{
@@ -1741,7 +1742,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_FALSE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, stencil_mask);
renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
@@ -1752,6 +1753,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gGL.popMatrix();
+#endif
}
void LLManipTranslate::renderText()
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..dd4ae4d201 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -758,7 +758,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type&
if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
// If already initialized, just confirm the status so the callback gets called
- setSLMStatus(mMarketPlaceStatus);
+ if (mMarketPlaceFailureReason.empty())
+ {
+ setSLMStatus(mMarketPlaceStatus);
+ }
+ else
+ {
+ setSLMConnectionFailure(mMarketPlaceFailureReason);
+ }
}
else
{
@@ -799,28 +806,27 @@ void LLMarketplaceData::getMerchantStatusCoro()
if (httpCode == HTTP_NOT_FOUND)
{
log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
}
else if (httpCode == HTTP_SERVICE_UNAVAILABLE)
{
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
- else if (httpCode == HTTP_INTERNAL_ERROR)
+ else
{
- // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
<< ", reason : " << status.toString()
<< ", code : " << result["error_code"].asString()
<< ", description : " << result["error_description"].asString() << LL_ENDL;
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
- }
- else
- {
- std::string err_code = result["error_code"].asString();
- //std::string err_description = result["error_description"].asString();
- log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]);
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ std::string reason = status.toString();
+ if (reason.empty())
+ {
+ reason = result["error_code"].asString();
+ }
+ // Since user might not even have a marketplace, there is no reason to report the error
+ // to the user, instead write it down into listings' floater
+ LLMarketplaceData::instance().setSLMConnectionFailure(reason);
}
return;
}
@@ -1298,6 +1304,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
void LLMarketplaceData::setSLMStatus(U32 status)
{
mMarketPlaceStatus = status;
+ mMarketPlaceFailureReason.clear();
+ if (mStatusUpdatedSignal)
+ {
+ (*mStatusUpdatedSignal)();
+ }
+}
+
+void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason)
+{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ mMarketPlaceFailureReason = reason;
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..088507d850 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
+ std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }
void setSLMStatus(U32 status);
+ void setSLMConnectionFailure(const std::string& reason);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
@@ -272,6 +274,7 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
+ std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
new file mode 100644
index 0000000000..a6d2729dfa
--- /dev/null
+++ b/indra/newview/llmaterialeditor.cpp
@@ -0,0 +1,2616 @@
+/**
+ * @file llmaterialeditor.cpp
+ * @brief Implementation of the gltf material editor
+ *
+ * $LicenseInfo:firstyear=2022&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmaterialeditor.h"
+
+#include "llagent.h"
+#include "llagentbenefits.h"
+#include "llappviewer.h"
+#include "llcombobox.h"
+#include "llfloaterreg.h"
+#include "llfilesystem.h"
+#include "llgltfmateriallist.h"
+#include "llinventorymodel.h"
+#include "llnotificationsutil.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewermenufile.h"
+#include "llviewertexture.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llstatusbar.h" // can_afford_transaction()
+#include "llviewerinventory.h"
+#include "llinventory.h"
+#include "llviewerregion.h"
+#include "llvovolume.h"
+#include "roles_constants.h"
+#include "llviewerobjectlist.h"
+#include "llsdserialize.h"
+#include "llimagej2c.h"
+#include "llviewertexturelist.h"
+#include "llfloaterperms.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include "lltinygltfhelper.h"
+#include <strstream>
+
+
+const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color";
+const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal";
+const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness";
+const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive";
+
+const LLUUID LIVE_MATERIAL_EDITOR_KEY("6cf97162-8b68-49eb-b627-79886c9fd17d");
+
+// Dirty flags
+static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;
+static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1;
+static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2;
+
+static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3;
+
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6;
+
+static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7;
+static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8;
+
+static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9;
+static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10;
+static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11;
+
+LLFloaterComboOptions::LLFloaterComboOptions()
+ : LLFloater(LLSD())
+{
+ buildFromFile("floater_combobox_ok_cancel.xml");
+}
+
+LLFloaterComboOptions::~LLFloaterComboOptions()
+{
+
+}
+
+BOOL LLFloaterComboOptions::postBuild()
+{
+ mConfirmButton = getChild<LLButton>("combo_ok", TRUE);
+ mCancelButton = getChild<LLButton>("combo_cancel", TRUE);
+ mComboOptions = getChild<LLComboBox>("combo_options", TRUE);
+ mComboText = getChild<LLTextBox>("combo_text", TRUE);
+
+ mConfirmButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onConfirm(); });
+ mCancelButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onCancel(); });
+
+ return TRUE;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = new LLFloaterComboOptions();
+ if (combo_picker)
+ {
+ combo_picker->mCallback = callback;
+ combo_picker->setTitle(title);
+
+ combo_picker->mComboText->setText(description);
+
+ std::list<std::string>::const_iterator iter = options.begin();
+ std::list<std::string>::const_iterator end = options.end();
+ for (; iter != end; iter++)
+ {
+ combo_picker->mComboOptions->addSimpleElement(*iter);
+ }
+ combo_picker->mComboOptions->selectFirstItem();
+
+ combo_picker->openFloater(LLSD(title));
+ combo_picker->setFocus(TRUE);
+ combo_picker->center();
+ }
+ return combo_picker;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = showUI(callback, title, description, options);
+ if (combo_picker)
+ {
+ combo_picker->mConfirmButton->setLabel(ok_text);
+ combo_picker->mCancelButton->setLabel(cancel_text);
+ }
+ return combo_picker;
+}
+
+void LLFloaterComboOptions::onConfirm()
+{
+ mCallback(mComboOptions->getSimple(), mComboOptions->getCurrentIndex());
+ closeFloater();
+}
+
+void LLFloaterComboOptions::onCancel()
+{
+ mCallback(std::string(), -1);
+ closeFloater();
+}
+
+class LLMaterialEditorCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLMaterialEditorCopiedCallback(
+ const std::string &buffer,
+ const LLSD &old_key,
+ bool has_unsaved_changes)
+ : mBuffer(buffer),
+ mOldKey(old_key),
+ mHasUnsavedChanges(has_unsaved_changes)
+ {}
+
+ LLMaterialEditorCopiedCallback(
+ const LLSD &old_key,
+ const std::string &new_name)
+ : mOldKey(old_key),
+ mNewName(new_name),
+ mHasUnsavedChanges(false)
+ {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mNewName.empty())
+ {
+ // making a copy from a notecard doesn't change name, do it now
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item->getName() != mNewName)
+ {
+ LLSD updates;
+ updates["name"] = mNewName;
+ update_inventory_item(inv_item_id, updates, NULL);
+ }
+ }
+ LLMaterialEditor::finishSaveAs(mOldKey, inv_item_id, mBuffer, mHasUnsavedChanges);
+ }
+
+private:
+ std::string mBuffer;
+ LLSD mOldKey;
+ std::string mNewName;
+ bool mHasUnsavedChanges;
+};
+
+///----------------------------------------------------------------------------
+/// Class LLMaterialEditor
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLMaterialEditor::LLMaterialEditor(const LLSD& key)
+ : LLPreview(key)
+ , mUnsavedChanges(0)
+ , mExpectedUploadCost(0)
+ , mUploadingTexturesCount(0)
+{
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+void LLMaterialEditor::setObjectID(const LLUUID& object_id)
+{
+ LLPreview::setObjectID(object_id);
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+void LLMaterialEditor::setAuxItem(const LLInventoryItem* item)
+{
+ LLPreview::setAuxItem(item);
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+BOOL LLMaterialEditor::postBuild()
+{
+ mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture");
+ mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture");
+ mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture");
+ mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture");
+
+ mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2));
+ mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2));
+ mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2));
+ mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2));
+
+ childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this));
+ childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this));
+ childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this));
+
+ S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+
+ boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
+ {
+ const U32 *flag = (const U32*)userData;
+ markChangesUnsaved(*flag);
+ // Apply changes to object live
+ applyToSelection();
+ };
+
+ childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY);
+
+ // BaseColor
+ childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
+ childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY);
+ childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
+ childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY);
+
+ // Metallic-Roughness
+ childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY);
+ childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY);
+
+ // Emissive
+ childSetCommitCallback("emissive color", changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY);
+
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0));
+
+ // Todo:
+ // Disable/enable setCanApplyImmediately() based on
+ // working from inventory, upload or editing inworld
+
+ return LLPreview::postBuild();
+}
+
+void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
+{
+ if (app_quitting)
+ {
+ closeFloater(app_quitting);
+ }
+ else
+ {
+ onClickCancel();
+ }
+}
+
+void LLMaterialEditor::onClose(bool app_quitting)
+{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
+
+ LLPreview::onClose(app_quitting);
+}
+
+LLUUID LLMaterialEditor::getBaseColorId()
+{
+ return mBaseColorTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setBaseColorId(const LLUUID& id)
+{
+ mBaseColorTextureCtrl->setValue(id);
+ mBaseColorTextureCtrl->setDefaultImageAssetID(id);
+ mBaseColorTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id)
+{
+ // Might be better to use local textures and
+ // assign a fee in case of a local texture
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("base_color_upload_fee", getString("upload_fee_string"));
+ // Only set if we will need to upload this texture
+ mBaseColorTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getBaseColor()
+{
+ LLColor4 ret = linearColor4(LLColor4(childGetValue("base color")));
+ ret.mV[3] = getTransparency();
+ return ret;
+}
+
+void LLMaterialEditor::setBaseColor(const LLColor4& color)
+{
+ childSetValue("base color", srgbColor4(color).getValue());
+ setTransparency(color.mV[3]);
+}
+
+F32 LLMaterialEditor::getTransparency()
+{
+ return childGetValue("transparency").asReal();
+}
+
+void LLMaterialEditor::setTransparency(F32 transparency)
+{
+ childSetValue("transparency", transparency);
+}
+
+std::string LLMaterialEditor::getAlphaMode()
+{
+ return childGetValue("alpha mode").asString();
+}
+
+void LLMaterialEditor::setAlphaMode(const std::string& alpha_mode)
+{
+ childSetValue("alpha mode", alpha_mode);
+}
+
+F32 LLMaterialEditor::getAlphaCutoff()
+{
+ return childGetValue("alpha cutoff").asReal();
+}
+
+void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff)
+{
+ childSetValue("alpha cutoff", alpha_cutoff);
+}
+
+void LLMaterialEditor::setMaterialName(const std::string &name)
+{
+ setTitle(name);
+ mMaterialName = name;
+}
+
+LLUUID LLMaterialEditor::getMetallicRoughnessId()
+{
+ return mMetallicTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id)
+{
+ mMetallicTextureCtrl->setValue(id);
+ mMetallicTextureCtrl->setDefaultImageAssetID(id);
+ mMetallicTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("metallic_upload_fee", getString("upload_fee_string"));
+ mMetallicTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+}
+
+F32 LLMaterialEditor::getMetalnessFactor()
+{
+ return childGetValue("metalness factor").asReal();
+}
+
+void LLMaterialEditor::setMetalnessFactor(F32 factor)
+{
+ childSetValue("metalness factor", factor);
+}
+
+F32 LLMaterialEditor::getRoughnessFactor()
+{
+ return childGetValue("roughness factor").asReal();
+}
+
+void LLMaterialEditor::setRoughnessFactor(F32 factor)
+{
+ childSetValue("roughness factor", factor);
+}
+
+LLUUID LLMaterialEditor::getEmissiveId()
+{
+ return mEmissiveTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setEmissiveId(const LLUUID& id)
+{
+ mEmissiveTextureCtrl->setValue(id);
+ mEmissiveTextureCtrl->setDefaultImageAssetID(id);
+ mEmissiveTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("emissive_upload_fee", getString("upload_fee_string"));
+ mEmissiveTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getEmissiveColor()
+{
+ return linearColor4(LLColor4(childGetValue("emissive color")));
+}
+
+void LLMaterialEditor::setEmissiveColor(const LLColor4& color)
+{
+ childSetValue("emissive color", srgbColor4(color).getValue());
+}
+
+LLUUID LLMaterialEditor::getNormalId()
+{
+ return mNormalTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setNormalId(const LLUUID& id)
+{
+ mNormalTextureCtrl->setValue(id);
+ mNormalTextureCtrl->setDefaultImageAssetID(id);
+ mNormalTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setNormalUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("normal_upload_fee", getString("upload_fee_string"));
+ mNormalTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
+}
+
+bool LLMaterialEditor::getDoubleSided()
+{
+ return childGetValue("double sided").asBoolean();
+}
+
+void LLMaterialEditor::setDoubleSided(bool double_sided)
+{
+ childSetValue("double sided", double_sided);
+}
+
+void LLMaterialEditor::resetUnsavedChanges()
+{
+ mUnsavedChanges = 0;
+ childSetVisible("unsaved_changes", false);
+ setCanSave(false);
+
+ mExpectedUploadCost = 0;
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+}
+
+void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
+{
+ mUnsavedChanges |= dirty_flag;
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ if (mUnsavedChanges)
+ {
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ LLPermissions perm(item->getPermissions());
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+ bool source_notecard = mNotecardInventoryID.notNull();
+
+ setCanSave(allow_modify && !source_library && !source_notecard);
+ }
+ }
+ else
+ {
+ setCanSave(false);
+ }
+
+ S32 upload_texture_count = 0;
+ if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId())
+ {
+ upload_texture_count++;
+ }
+ if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId())
+ {
+ upload_texture_count++;
+ }
+ if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId())
+ {
+ upload_texture_count++;
+ }
+ if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId())
+ {
+ upload_texture_count++;
+ }
+
+ mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+}
+
+void LLMaterialEditor::setCanSaveAs(bool value)
+{
+ childSetEnabled("save_as", value);
+}
+
+void LLMaterialEditor::setCanSave(bool value)
+{
+ childSetEnabled("save", value);
+}
+
+void LLMaterialEditor::setEnableEditing(bool can_modify)
+{
+ childSetEnabled("double sided", can_modify);
+
+ // BaseColor
+ childSetEnabled("base color", can_modify);
+ childSetEnabled("transparency", can_modify);
+ childSetEnabled("alpha mode", can_modify);
+ childSetEnabled("alpha cutoff", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Emissive
+ childSetEnabled("emissive color", can_modify);
+
+ mBaseColorTextureCtrl->setEnabled(can_modify);
+ mMetallicTextureCtrl->setEnabled(can_modify);
+ mEmissiveTextureCtrl->setEnabled(can_modify);
+ mNormalTextureCtrl->setEnabled(can_modify);
+}
+
+void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ // might be better to use arrays, to have a single callback
+ // and not to repeat the same thing for each tecture control
+ LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID();
+ if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull())
+ {
+ childSetValue("base_color_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ // Texture picker has 'apply now' with 'cancel' support.
+ // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in
+ // case user decides to cancel changes.
+ // Without mBaseColorFetched, viewer will eventually cleanup
+ // the texture that is not in use
+ childSetValue("base_color_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitMetallicTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mMetallicTextureCtrl->getValue().asUUID();
+ if (new_val == mMetallicTextureUploadId && mMetallicTextureUploadId.notNull())
+ {
+ childSetValue("metallic_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("metallic_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitEmissiveTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mEmissiveTextureCtrl->getValue().asUUID();
+ if (new_val == mEmissiveTextureUploadId && mEmissiveTextureUploadId.notNull())
+ {
+ childSetValue("emissive_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("emissive_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCommitNormalTexture(LLUICtrl * ctrl, const LLSD & data)
+{
+ LLUUID new_val = mNormalTextureCtrl->getValue().asUUID();
+ if (new_val == mNormalTextureUploadId && mNormalTextureUploadId.notNull())
+ {
+ childSetValue("normal_upload_fee", getString("upload_fee_string"));
+ }
+ else
+ {
+ childSetValue("normal_upload_fee", getString("no_upload_fee_string"));
+ }
+ markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
+ applyToSelection();
+}
+
+
+static void write_color(const LLColor4& color, std::vector<double>& c)
+{
+ for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component
+ {
+ c[i] = color.mV[i];
+ }
+}
+
+static U32 write_texture(const LLUUID& id, tinygltf::Model& model)
+{
+ tinygltf::Image image;
+ image.uri = id.asString();
+ model.images.push_back(image);
+ U32 image_idx = model.images.size() - 1;
+
+ tinygltf::Texture texture;
+ texture.source = image_idx;
+ model.textures.push_back(texture);
+ U32 texture_idx = model.textures.size() - 1;
+
+ return texture_idx;
+}
+
+
+void LLMaterialEditor::onClickSave()
+{
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ applyToSelection();
+ saveIfNeeded();
+}
+
+
+std::string LLMaterialEditor::getGLTFJson(bool prettyprint)
+{
+ tinygltf::Model model;
+ getGLTFModel(model);
+
+ std::ostringstream str;
+
+ tinygltf::TinyGLTF gltf;
+
+ gltf.WriteGltfSceneToStream(&model, str, prettyprint, false);
+
+ std::string dump = str.str();
+
+ return dump;
+}
+
+void LLMaterialEditor::getGLBData(std::vector<U8>& data)
+{
+ tinygltf::Model model;
+ getGLTFModel(model);
+
+ std::ostringstream str;
+
+ tinygltf::TinyGLTF gltf;
+
+ gltf.WriteGltfSceneToStream(&model, str, false, true);
+
+ std::string dump = str.str();
+
+ data.resize(dump.length());
+
+ memcpy(&data[0], dump.c_str(), dump.length());
+}
+
+void LLMaterialEditor::getGLTFModel(tinygltf::Model& model)
+{
+ model.materials.resize(1);
+ tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness;
+
+ // write base color
+ LLColor4 base_color = getBaseColor();
+ base_color.mV[3] = getTransparency();
+ write_color(base_color, pbrMaterial.baseColorFactor);
+
+ model.materials[0].alphaCutoff = getAlphaCutoff();
+ model.materials[0].alphaMode = getAlphaMode();
+
+ LLUUID base_color_id = getBaseColorId();
+
+ if (base_color_id.notNull())
+ {
+ U32 texture_idx = write_texture(base_color_id, model);
+
+ pbrMaterial.baseColorTexture.index = texture_idx;
+ }
+
+ // write metallic/roughness
+ F32 metalness = getMetalnessFactor();
+ F32 roughness = getRoughnessFactor();
+
+ pbrMaterial.metallicFactor = metalness;
+ pbrMaterial.roughnessFactor = roughness;
+
+ LLUUID mr_id = getMetallicRoughnessId();
+ if (mr_id.notNull())
+ {
+ U32 texture_idx = write_texture(mr_id, model);
+ pbrMaterial.metallicRoughnessTexture.index = texture_idx;
+ }
+
+ //write emissive
+ LLColor4 emissive_color = getEmissiveColor();
+ model.materials[0].emissiveFactor.resize(3);
+ write_color(emissive_color, model.materials[0].emissiveFactor);
+
+ LLUUID emissive_id = getEmissiveId();
+ if (emissive_id.notNull())
+ {
+ U32 idx = write_texture(emissive_id, model);
+ model.materials[0].emissiveTexture.index = idx;
+ }
+
+ //write normal
+ LLUUID normal_id = getNormalId();
+ if (normal_id.notNull())
+ {
+ U32 idx = write_texture(normal_id, model);
+ model.materials[0].normalTexture.index = idx;
+ }
+
+ //write doublesided
+ model.materials[0].doubleSided = getDoubleSided();
+
+ model.asset.version = "2.0";
+}
+
+std::string LLMaterialEditor::getEncodedAsset()
+{
+ LLSD asset;
+ asset["version"] = "1.0";
+ asset["type"] = "GLTF 2.0";
+ asset["data"] = getGLTFJson(false);
+
+ std::ostringstream str;
+ LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
+
+ return str.str();
+}
+
+bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
+{
+ LLSD asset;
+
+ std::istrstream str(&buffer[0], buffer.size());
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && asset["version"] == "1.0")
+ {
+ if (asset.has("type") && asset["type"] == "GLTF 2.0")
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ tinygltf::TinyGLTF gltf;
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
+ {
+ // assets are only supposed to have one item
+ return setFromGltfModel(model_in, 0, true);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to decode material asset: " << LL_ENDL;
+ LL_WARNS() << warn_msg << LL_ENDL;
+ LL_WARNS() << error_msg << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+
+ return false;
+}
+
+/**
+ * Build a description of the material we just imported.
+ * Currently this means a list of the textures present but we
+ * may eventually want to make it more complete - will be guided
+ * by what the content creators say they need.
+ */
+const std::string LLMaterialEditor::buildMaterialDescription()
+{
+ std::ostringstream desc;
+ desc << LLTrans::getString("Material Texture Name Header");
+
+ // add the texture names for each just so long as the material
+ // we loaded has an entry for it (i think testing the texture
+ // control UUI for NULL is a valid metric for if it was loaded
+ // or not but I suspect this code will change a lot so may need
+ // to revisit
+ if (!mBaseColorTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mBaseColorName;
+ desc << ", ";
+ }
+ if (!mMetallicTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mMetallicRoughnessName;
+ desc << ", ";
+ }
+ if (!mEmissiveTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mEmissiveName;
+ desc << ", ";
+ }
+ if (!mNormalTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mNormalName;
+ }
+
+ // trim last char if it's a ',' in case there is no normal texture
+ // present and the code above inserts one
+ // (no need to check for string length - always has initial string)
+ std::string::iterator iter = desc.str().end() - 1;
+ if (*iter == ',')
+ {
+ desc.str().erase(iter);
+ }
+
+ // sanitize the material description so that it's compatible with the inventory
+ // note: split this up because clang doesn't like operating directly on the
+ // str() - error: lvalue reference to type 'basic_string<...>' cannot bind to a
+ // temporary of type 'basic_string<...>'
+ std::string inv_desc = desc.str();
+ LLInventoryObject::correctInventoryName(inv_desc);
+
+ return inv_desc;
+}
+
+bool LLMaterialEditor::saveIfNeeded()
+{
+ if (mUploadingTexturesCount > 0)
+ {
+ // upload already in progress
+ // wait until textures upload
+ // will retry saving on callback
+ return true;
+ }
+
+ if (saveTextures() > 0)
+ {
+ // started texture upload
+ setEnabled(false);
+ return true;
+ }
+
+ std::string buffer = getEncodedAsset();
+
+ const LLInventoryItem* item = getItem();
+ // save it out to database
+ if (item)
+ {
+ if (!saveToInventoryItem(buffer, mItemUUID, mObjectUUID))
+ {
+ return false;
+ }
+
+ if (mCloseAfterSave)
+ {
+ closeFloater();
+ }
+ else
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ }
+ else
+ { //make a new inventory item
+#if 1
+ // gen a new uuid for this asset
+ LLTransactionID tid;
+ tid.generate(); // timestamp-based randomization + uniquification
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+ std::string res_desc = buildMaterialDescription();
+ U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ?
+
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc,
+ LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm,
+ new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ // create_inventory_item doesn't allow presetting some permissions, fix it now
+ LLPermissions perm = item->getPermissions();
+ if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Materials")
+ || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Materials"))
+ {
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+
+ // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem()
+ LLResourceUploadInfo::ptr_t uploadInfo =
+ std::make_shared<LLBufferedAssetUploadInfo>(
+ inv_item_id,
+ LLAssetType::AT_MATERIAL,
+ output,
+ [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) {
+ LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
+ LLSD params = llsd::map("ASSET_ID", new_asset_id);
+ LLNotificationsUtil::add("MaterialCreated", params);
+ });
+
+ // todo: apply permissions from textures here if server doesn't
+ // if any texture is 'no transfer', material should be 'no transfer' as well
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string agent_url(region->getCapability("UpdateMaterialAgentInventory"));
+ if (agent_url.empty())
+ {
+ LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL;
+ }
+ LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
+ }
+ })
+ );
+
+ // We do not update floater with uploaded asset yet, so just close it.
+ closeFloater();
+#endif
+ }
+
+ return true;
+}
+
+// static
+bool LLMaterialEditor::saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id)
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL;
+ return false;
+ }
+ std::string agent_url = region->getCapability("UpdateMaterialAgentInventory");
+ std::string task_url = region->getCapability("UpdateMaterialTaskInventory");
+
+ if (!agent_url.empty() && !task_url.empty())
+ {
+ std::string url;
+ LLResourceUploadInfo::ptr_t uploadInfo;
+
+ if (task_id.isNull() && !agent_url.empty())
+ {
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(item_id, LLAssetType::AT_MATERIAL, buffer,
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) {
+ LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId);
+ });
+ url = agent_url;
+ }
+ else if (!task_id.isNull() && !task_url.empty())
+ {
+ LLUUID object_uuid(task_id);
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(task_id, item_id, LLAssetType::AT_MATERIAL, buffer,
+ [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) {
+ LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid);
+ });
+ url = task_url;
+ }
+
+ if (!url.empty() && uploadInfo)
+ {
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+ else // !gAssetStorage
+ {
+ LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL;
+ return false;
+ }
+
+ // todo: apply permissions from textures here if server doesn't
+ // if any texture is 'no transfer', material should be 'no transfer' as well
+
+ return true;
+}
+
+void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId)
+{
+ // Update the UI with the new asset.
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(itemId));
+ if (me)
+ {
+ if (newItemId.isNull())
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ }
+ else if (newItemId.notNull())
+ {
+ // Not supposed to happen?
+ me->refreshFromInventory(newItemId);
+ }
+ else
+ {
+ me->refreshFromInventory(itemId);
+ }
+ }
+}
+
+void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId)
+{
+ LLSD floater_key;
+ floater_key["taskid"] = taskId;
+ floater_key["itemid"] = itemId;
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (me)
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ me->setEnabled(true);
+ }
+}
+
+void LLMaterialEditor::finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes)
+{
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", oldKey);
+ LLViewerInventoryItem* item = gInventory.getItem(newItemId);
+ if (item)
+ {
+ if (me)
+ {
+ me->mItemUUID = newItemId;
+ me->mObjectUUID = LLUUID::null;
+ me->mNotecardInventoryID = LLUUID::null;
+ me->mNotecardObjectID = LLUUID::null;
+ me->mAuxItem = nullptr;
+ me->setKey(LLSD(newItemId)); // for findTypedInstance
+ me->setMaterialName(item->getName());
+ if (has_unsaved_changes)
+ {
+ if (!saveToInventoryItem(buffer, newItemId, LLUUID::null))
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ me->loadAsset();
+ me->setEnabled(true);
+ }
+ }
+ else if(has_unsaved_changes)
+ {
+ saveToInventoryItem(buffer, newItemId, LLUUID::null);
+ }
+ }
+ else if (me)
+ {
+ me->setEnabled(true);
+ LL_WARNS() << "Item does not exist" << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id)
+{
+ if (new_item_id.notNull())
+ {
+ mItemUUID = new_item_id;
+ if (mNotecardInventoryID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["objectid"] = mNotecardObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ setKey(floater_key);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = new_item_id;
+ floater_key["itemid"] = mObjectUUID;
+ setKey(floater_key);
+ }
+ else
+ {
+ setKey(LLSD(new_item_id));
+ }
+ }
+ LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL;
+ loadAsset();
+}
+
+
+void LLMaterialEditor::onClickSaveAs()
+{
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ LLSD args;
+ args["DESC"] = mMaterialName;
+
+ LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
+}
+
+void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string new_name = response["message"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (!new_name.empty())
+ {
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+ if (item)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = item->getParentUUID();
+ if (mObjectUUID.notNull() || marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ }
+
+ // A two step process, first copy an existing item, then create new asset
+ if (mNotecardInventoryID.notNull())
+ {
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(getKey(), new_name);
+ copy_inventory_from_notecard(parent_id,
+ mNotecardObjectID,
+ mNotecardInventoryID,
+ mAuxItem.get(),
+ gInventoryCallbacks.registerCB(cb));
+ }
+ else
+ {
+ std::string buffer = getEncodedAsset();
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges);
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ new_name,
+ cb);
+ }
+
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ else
+ {
+ setMaterialName(new_name);
+ onClickSave();
+ }
+ }
+ else
+ {
+ LLNotificationsUtil::add("InvalidMaterialName");
+ }
+ }
+}
+
+void LLMaterialEditor::onClickCancel()
+{
+ if (mUnsavedChanges)
+ {
+ LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2));
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ if (mIsOverride && !mObjectOverridesSavedValues.empty())
+ {
+ // Reapply ids back onto selection.
+ // TODO: monitor selection changes and resave on selection changes
+ struct g : public LLSelectedObjectFunctor
+ {
+ g(LLMaterialEditor* me) : mEditor(me) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp || !objectp->permModify())
+ {
+ return false;
+ }
+
+ U32 local_id = objectp->getLocalID();
+ if (mEditor->mObjectOverridesSavedValues.find(local_id) == mEditor->mObjectOverridesSavedValues.end())
+ {
+ return false;
+ }
+
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ for (U8 te = 0; te < num_tes; te++)
+ {
+ if (mEditor->mObjectOverridesSavedValues[local_id].size() > te
+ && objectp->getTE(te)->isSelected())
+ {
+ objectp->setRenderMaterialID(
+ te,
+ mEditor->mObjectOverridesSavedValues[local_id][te],
+ false /*wait for bulk update*/);
+ }
+ }
+ return true;
+ }
+ LLMaterialEditor* mEditor;
+ } restorefunc(this);
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&restorefunc);
+
+ struct f : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc;
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
+ }
+
+ closeFloater();
+ }
+}
+
+static void pack_textures(
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLImageJ2C>& base_color_j2c,
+ LLPointer<LLImageJ2C>& normal_j2c,
+ LLPointer<LLImageJ2C>& mr_j2c,
+ LLPointer<LLImageJ2C>& emissive_j2c)
+{
+ // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful
+
+ if (base_color_img)
+ {
+ base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img);
+ LL_INFOS() << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (normal_img)
+ {
+ normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img);
+
+ LLPointer<LLImageJ2C> test;
+ test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true);
+
+ S32 lossy_bytes = normal_j2c->getDataSize();
+ S32 lossless_bytes = test->getDataSize();
+
+ LL_INFOS() << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL;
+
+ normal_j2c = test;
+ }
+
+ if (mr_img)
+ {
+ mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img);
+ LL_INFOS() << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (emissive_img)
+ {
+ emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img);
+ LL_INFOS() << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index)
+{
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ bool loaded = false;
+ tinygltf::Model model_in;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+ else
+ { // file is ascii
+ loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+
+ if (!loaded)
+ {
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (index >= 0 && model_in.materials.size() <= index)
+ {
+ // material is missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+
+ if (index >= 0)
+ {
+ // Prespecified material
+ me->loadMaterial(model_in, filename_lc, index);
+ }
+ else if (model_in.materials.size() == 1)
+ {
+ // Only one, just load it
+ me->loadMaterial(model_in, filename_lc, 0);
+ }
+ else
+ {
+ // Promt user to select material
+ std::list<std::string> material_list;
+ std::vector<tinygltf::Material>::const_iterator mat_iter = model_in.materials.begin();
+ std::vector<tinygltf::Material>::const_iterator mat_end = model_in.materials.end();
+ for (; mat_iter != mat_end; mat_iter++)
+ {
+ std::string mat_name = mat_iter->name;
+ if (mat_name.empty())
+ {
+ material_list.push_back("Material " + std::to_string(material_list.size()));
+ }
+ else
+ {
+ material_list.push_back(mat_name);
+ }
+ }
+ LLFloaterComboOptions::showUI(
+ [me, model_in, filename_lc](const std::string& option, S32 index)
+ {
+ me->loadMaterial(model_in, filename_lc, index);
+ },
+ me->getString("material_selection_title"),
+ me->getString("material_selection_text"),
+ material_list
+ );
+ }
+}
+void LLMaterialEditor::onSelectionChanged()
+{
+ mUnsavedChanges = 0;
+ clearTextures();
+ setFromSelection();
+ saveLiveValues();
+}
+
+void LLMaterialEditor::saveLiveValues()
+{
+ // Collect ids to be able to revert overrides.
+ // TODO: monitor selection changes and resave on selection changes
+ mObjectOverridesSavedValues.clear();
+ struct g : public LLSelectedObjectFunctor
+ {
+ g(LLMaterialEditor* me) : mEditor(me) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp)
+ {
+ return false;
+ }
+
+ U32 local_id = objectp->getLocalID();
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ for (U8 te = 0; te < num_tes; te++)
+ {
+ LLUUID mat_id = objectp->getRenderMaterialID(te);
+ mEditor->mObjectOverridesSavedValues[local_id].push_back(mat_id);
+ }
+ return true;
+ }
+ LLMaterialEditor* mEditor;
+ } savefunc(this);
+ LLSelectMgr::getInstance()->getSelection()->applyToObjects(&savefunc);
+}
+
+void LLMaterialEditor::loadLive()
+{
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY));
+ if (me)
+ {
+ me->setFromSelection();
+ me->mIsOverride = true;
+ me->setTitle(me->getString("material_override_title"));
+ me->childSetVisible("save", false);
+ me->childSetVisible("save_as", false);
+
+ // Set up for selection changes updates
+ if (!me->mSelectionUpdateSlot.connected())
+ {
+ me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me));
+ }
+ // Collect ids to be able to revert overrides on cancel.
+ me->saveLiveValues();
+
+ me->openFloater();
+ me->setFocus(TRUE);
+ }
+}
+
+void LLMaterialEditor::loadObjectSave()
+{
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY));
+ if (me->setFromSelection())
+ {
+ me->mIsOverride = false;
+ me->childSetVisible("save", false);
+ me->openFloater();
+ me->setFocus(TRUE);
+ }
+}
+
+void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id)
+{
+ if (asset_id.isNull())
+ {
+ LL_WARNS() << "Trying to open material with null id" << LL_ENDL;
+ return;
+ }
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+ me->mMaterialName = LLTrans::getString("New Material");
+ me->setTitle(me->mMaterialName);
+ me->setFromGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ me->openFloater();
+ me->setFocus(TRUE);
+}
+
+void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index)
+{
+ if (model_in.materials.size() <= index)
+ {
+ return;
+ }
+ std::string folder = gDirUtilp->getDirName(filename_lc);
+
+ tinygltf::Material material_in = model_in.materials[index];
+
+ tinygltf::Model model_out;
+ model_out.asset.version = "2.0";
+ model_out.materials.resize(1);
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_color_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mBaseColorName);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mMetallicRoughnessName);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mEmissiveName);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ std::string tmp;
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp);
+ }
+
+ LLTinyGLTFHelper::initFetchedTextures(material_in, base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched);
+ pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C);
+
+ LLUUID base_color_id;
+ if (mBaseColorFetched.notNull())
+ {
+ mBaseColorFetched->forceToSaveRawImage(0, F32_MAX);
+ base_color_id = mBaseColorFetched->getID();
+
+ if (mBaseColorName.empty())
+ {
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID normal_id;
+ if (mNormalFetched.notNull())
+ {
+ mNormalFetched->forceToSaveRawImage(0, F32_MAX);
+ normal_id = mNormalFetched->getID();
+
+ if (mNormalName.empty())
+ {
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID mr_id;
+ if (mMetallicRoughnessFetched.notNull())
+ {
+ mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX);
+ mr_id = mMetallicRoughnessFetched->getID();
+
+ if (mMetallicRoughnessName.empty())
+ {
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID emissive_id;
+ if (mEmissiveFetched.notNull())
+ {
+ mEmissiveFetched->forceToSaveRawImage(0, F32_MAX);
+ emissive_id = mEmissiveFetched->getID();
+
+ if (mEmissiveName.empty())
+ {
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ }
+ }
+
+ setBaseColorId(base_color_id);
+ setBaseColorUploadId(base_color_id);
+ setMetallicRoughnessId(mr_id);
+ setMetallicRoughnessUploadId(mr_id);
+ setEmissiveId(emissive_id);
+ setEmissiveUploadId(emissive_id);
+ setNormalId(normal_id);
+ setNormalUploadId(normal_id);
+
+ setFromGltfModel(model_in, index);
+
+ setFromGltfMetaData(filename_lc, model_in, index);
+
+ markChangesUnsaved(U32_MAX);
+
+ openFloater();
+ setFocus(TRUE);
+
+ applyToSelection();
+}
+
+bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures)
+{
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& material_in = model.materials[index];
+
+ if (set_textures)
+ {
+ S32 index;
+ LLUUID id;
+
+ // get base color texture
+ index = material_in.pbrMetallicRoughness.baseColorTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setBaseColorId(id);
+ }
+ else
+ {
+ setBaseColorId(LLUUID::null);
+ }
+
+ // get normal map
+ index = material_in.normalTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setNormalId(id);
+ }
+ else
+ {
+ setNormalId(LLUUID::null);
+ }
+
+ // get metallic-roughness texture
+ index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setMetallicRoughnessId(id);
+ }
+ else
+ {
+ setMetallicRoughnessId(LLUUID::null);
+ }
+
+ // get emissive texture
+ index = material_in.emissiveTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setEmissiveId(id);
+ }
+ else
+ {
+ setEmissiveId(LLUUID::null);
+ }
+ }
+
+ setAlphaMode(material_in.alphaMode);
+ setAlphaCutoff(material_in.alphaCutoff);
+
+ setBaseColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor));
+ setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor));
+
+ setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor);
+ setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor);
+
+ setDoubleSided(material_in.doubleSided);
+ }
+
+ return true;
+}
+
+/**
+ * Build a texture name from the contents of the (in tinyGLFT parlance)
+ * Image URI. This often is filepath to the original image on the users'
+ * local file system.
+ */
+const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type)
+{
+ // getBaseFileName() works differently on each platform and file patchs
+ // can contain both types of delimiter so unify them then extract the
+ // base name (no path or extension)
+ std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]);
+ std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]);
+ const bool strip_extension = true;
+ std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension);
+
+ // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :)
+ const int max_texture_name_length = 64;
+ if (stripped_uri.length() > max_texture_name_length)
+ {
+ stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1);
+ }
+
+ // We intend to append the type of texture (base color, emissive etc.) to the
+ // name of the texture but sometimes the creator already did that. To try
+ // to avoid repeats (not perfect), we look for the texture type in the name
+ // and if we find it, do not append the type, later on. One way this fails
+ // (and it's fine for now) is I see some texture/image uris have a name like
+ // "metallic roughness" and of course, that doesn't match our predefined
+ // name "metallicroughness" - consider fix later..
+ bool name_includes_type = false;
+ std::string stripped_uri_lower = stripped_uri;
+ LLStringUtil::toLower(stripped_uri_lower);
+ stripped_uri_lower.erase(std::remove_if(stripped_uri_lower.begin(), stripped_uri_lower.end(), isspace), stripped_uri_lower.end());
+ std::string texture_type_lower = texture_type;
+ LLStringUtil::toLower(texture_type_lower);
+ texture_type_lower.erase(std::remove_if(texture_type_lower.begin(), texture_type_lower.end(), isspace), texture_type_lower.end());
+ if (stripped_uri_lower.find(texture_type_lower) != std::string::npos)
+ {
+ name_includes_type = true;
+ }
+
+ // uri doesn't include the type at all
+ if (name_includes_type == false)
+ {
+ // uri doesn't include the type and the uri is not empty
+ // so we can include everything
+ if (stripped_uri.length() > 0)
+ {
+ // example "DamagedHelmet: base layer"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ else
+ // uri doesn't include the type (because the uri is empty)
+ // so we must reorganize the string a bit to include the name
+ // and an explicit name type
+ {
+ // example "DamagedHelmet: (Emissive)"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ }
+ else
+ // uri includes the type so just use it directly with the
+ // name of the material
+ {
+ return STRINGIZE(
+ // example: AlienBust: normal_layer
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri
+ );
+ }
+}
+
+/**
+ * Update the metadata for the material based on what we find in the loaded
+ * file (along with some assumptions and interpretations...). Fields include
+ * the name of the material, a material description and the names of the
+ * composite textures.
+ */
+void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index)
+{
+ // Use the name (without any path/extension) of the file that was
+ // uploaded as the base of the material name. Then if the name of the
+ // scene is present and not blank, append that and use the result as
+ // the name of the material. This is a first pass at creating a
+ // naming scheme that is useful to real content creators and hopefully
+ // avoid 500 materials in your inventory called "scene" or "Default"
+ const bool strip_extension = true;
+ std::string base_filename = gDirUtilp->getBaseFileName(filename, strip_extension);
+
+ // Extract the name of the scene. Note it is often blank or some very
+ // generic name like "Scene" or "Default" so using this in the name
+ // is less useful than you might imagine.
+ std::string material_name;
+ if (model.materials.size() > index && !model.materials[index].name.empty())
+ {
+ material_name = model.materials[index].name;
+ }
+ else if (model.scenes.size() > 0)
+ {
+ const tinygltf::Scene& scene_in = model.scenes[0];
+ if (scene_in.name.length())
+ {
+ material_name = scene_in.name;
+ }
+ else
+ {
+ // scene name is empty so no point using it
+ }
+ }
+ else
+ {
+ // scene name isn't present so no point using it
+ }
+
+ // If we have a valid material or scene name, use it to build the short and
+ // long versions of the material name. The long version is used
+ // as you might expect, for the material name. The short version is
+ // used as part of the image/texture name - the theory is that will
+ // allow content creators to track the material and the corresponding
+ // textures
+ if (material_name.length())
+ {
+ mMaterialNameShort = base_filename;
+
+ mMaterialName = STRINGIZE(
+ base_filename <<
+ " " <<
+ "(" <<
+ material_name <<
+ ")"
+ );
+ }
+ else
+ // otherwise, just use the trimmed filename as is
+ {
+ mMaterialNameShort = base_filename;
+ mMaterialName = base_filename;
+ }
+
+ // sanitize the material name so that it's compatible with the inventory
+ LLInventoryObject::correctInventoryName(mMaterialName);
+ LLInventoryObject::correctInventoryName(mMaterialNameShort);
+
+ // We also set the title of the floater to match the
+ // name of the material
+ setTitle(mMaterialName);
+
+ /**
+ * Extract / derive the names of each composite texture. For each, the
+ * index is used to to determine which of the "Images" is used. If the index
+ * is -1 then that texture type is not present in the material (Seems to be
+ * quite common that a material is missing 1 or more types of texture)
+ */
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& first_material = model.materials[index];
+
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ // note: unlike the other textures, base color doesn't have its own entry
+ // in the tinyGLTF Material struct. Rather, it is taken from a
+ // sub-texture in the pbrMetallicRoughness member
+ int index = first_material.pbrMetallicRoughness.baseColorTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ // sanitize the name we decide to use for each texture
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_BASE_COLOR_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mBaseColorName = texture_name;
+ }
+
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ index = first_material.emissiveTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mEmissiveName = texture_name;
+ }
+
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ index = first_material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mMetallicRoughnessName = texture_name;
+ }
+
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ index = first_material.normalTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mNormalName = texture_name;
+ }
+ }
+}
+
+void LLMaterialEditor::importMaterial()
+{
+ LLFilePickerReplyThread::startPicker(
+ [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)
+ {
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+ if (filenames.size() > 0)
+ {
+ LLMaterialEditor::loadMaterialFromFile(filenames[0], -1);
+ }
+ },
+ LLFilePicker::FFLOAD_MATERIAL,
+ true);
+}
+
+class LLRenderMaterialFunctor : public LLSelectedTEFunctor
+{
+public:
+ LLRenderMaterialFunctor(const LLUUID &id)
+ : mMatId(id)
+ {
+ }
+
+ bool apply(LLViewerObject* objectp, S32 te) override
+ {
+ if (objectp && objectp->permModify() && objectp->getVolume())
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)objectp;
+ vobjp->setRenderMaterialID(te, mMatId, false /*preview only*/);
+ vobjp->updateTEMaterialTextures(te);
+ }
+ return true;
+ }
+private:
+ LLUUID mMatId;
+};
+
+class LLRenderMaterialOverrideFunctor : public LLSelectedTEFunctor
+{
+public:
+ LLRenderMaterialOverrideFunctor(LLMaterialEditor * me, std::string const & url)
+ : mEditor(me), mCapUrl(url)
+ {
+
+ }
+
+ bool apply(LLViewerObject* objectp, S32 te) override
+ {
+ // post override from given object and te to the simulator
+ // requestData should have:
+ // object_id - UUID of LLViewerObject
+ // side - S32 index of texture entry
+ // gltf_json - String of GLTF json for override data
+
+ if (objectp && objectp->permModify() && objectp->getVolume())
+ {
+ // Get material from object
+ // Selection can cover multiple objects, and live editor is
+ // supposed to overwrite changed values only
+ LLTextureEntry* tep = objectp->getTE(te);
+ LLPointer<LLGLTFMaterial> material = tep->getGLTFMaterial();
+ if (material.isNull())
+ {
+ material = new LLGLTFMaterial();
+ }
+
+ // Override object's values with values from editor where appropriate
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY)
+ {
+ material->mBaseColor = mEditor->getBaseColor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY)
+ {
+ material->mBaseColor.mV[3] = mEditor->getTransparency();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY)
+ {
+ material->mBaseColorId = mEditor->getBaseColorId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY)
+ {
+ material->mNormalId = mEditor->getNormalId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
+ {
+ material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
+ {
+ material->mMetallicFactor = mEditor->getMetalnessFactor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY)
+ {
+ material->mRoughnessFactor = mEditor->getRoughnessFactor();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY)
+ {
+ material->mEmissiveColor = mEditor->getEmissiveColor();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY)
+ {
+ material->mEmissiveId = mEditor->getEmissiveId();
+ }
+
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY)
+ {
+ material->mDoubleSided = mEditor->getDoubleSided();
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY)
+ {
+ material->setAlphaMode(mEditor->getAlphaMode());
+ }
+ if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY)
+ {
+ material->mAlphaCutoff = mEditor->getAlphaCutoff();
+ }
+
+ std::string overrides_json = material->asJSON();
+
+ LLSD overrides = llsd::map(
+ "object_id", objectp->getID(),
+ "side", te,
+ "gltf_json", overrides_json
+ );
+ LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides));
+ }
+ return true;
+ }
+
+private:
+ LLMaterialEditor * mEditor;
+ std::string mCapUrl;
+};
+
+void LLMaterialEditor::applyToSelection()
+{
+ if (!mIsOverride)
+ {
+ // Only apply if working with 'live' materials
+ // Might need a better way to distinguish 'live' mode.
+ // But only one live edit is supposed to work at a time
+ // as a pair to tools floater.
+ return;
+ }
+
+ std::string url = gAgent.getRegionCapability("ModifyMaterialParams");
+ if (!url.empty())
+ {
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO figure out how to get the right asset id in cases where we don't have a good one
+ LLRenderMaterialOverrideFunctor override_func(this, url);
+ selected_objects->applyToTEs(&override_func);
+ }
+ else
+ {
+ LL_WARNS() << "not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL;
+
+ // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere.
+ LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial();
+ getGLTFMaterial(mat);
+ static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98");
+ gGLTFMaterialList.addMaterial(placeholder, mat);
+ LLRenderMaterialFunctor mat_func(placeholder);
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ selected_objects->applyToTEs(&mat_func);
+ }
+}
+
+void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
+{
+ mat->mBaseColor = getBaseColor();
+ mat->mBaseColor.mV[3] = getTransparency();
+ mat->mBaseColorId = getBaseColorId();
+
+ mat->mNormalId = getNormalId();
+
+ mat->mMetallicRoughnessId = getMetallicRoughnessId();
+ mat->mMetallicFactor = getMetalnessFactor();
+ mat->mRoughnessFactor = getRoughnessFactor();
+
+ mat->mEmissiveColor = getEmissiveColor();
+ mat->mEmissiveId = getEmissiveId();
+
+ mat->mDoubleSided = getDoubleSided();
+ mat->setAlphaMode(getAlphaMode());
+ mat->mAlphaCutoff = getAlphaCutoff();
+}
+
+void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
+{
+ setBaseColor(mat->mBaseColor);
+ setBaseColorId(mat->mBaseColorId);
+ setNormalId(mat->mNormalId);
+
+ setMetallicRoughnessId(mat->mMetallicRoughnessId);
+ setMetalnessFactor(mat->mMetallicFactor);
+ setRoughnessFactor(mat->mRoughnessFactor);
+
+ setEmissiveColor(mat->mEmissiveColor);
+ setEmissiveId(mat->mEmissiveId);
+
+ setDoubleSided(mat->mDoubleSided);
+ setAlphaMode(mat->getAlphaMode());
+ setAlphaCutoff(mat->mAlphaCutoff);
+}
+
+bool LLMaterialEditor::setFromSelection()
+{
+ struct LLSelectedTEGetGLTFRenderMaterial : public LLSelectedTEGetFunctor<LLPointer<LLGLTFMaterial> >
+ {
+ LLPointer<LLGLTFMaterial> get(LLViewerObject* objectp, S32 te_index)
+ {
+ if (!objectp)
+ {
+ return nullptr;
+ }
+ LLTextureEntry *tep = objectp->getTE(te_index);
+ if (!tep)
+ {
+ return nullptr;
+ }
+ return tep->getGLTFRenderMaterial(); // present user with combined override + asset
+ }
+ } func;
+
+ LLPointer<LLGLTFMaterial> mat;
+ bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat);
+ if (mat.notNull())
+ {
+ setFromGLTFMaterial(mat);
+ }
+ else
+ {
+ // pick defaults from a blank material;
+ LLGLTFMaterial blank_mat;
+ setFromGLTFMaterial(&blank_mat);
+ }
+
+ mBaseColorTextureCtrl->setTentative(!identical);
+ mMetallicTextureCtrl->setTentative(!identical);
+ mEmissiveTextureCtrl->setTentative(!identical);
+ mNormalTextureCtrl->setTentative(!identical);
+
+ return mat.notNull();
+}
+
+
+void LLMaterialEditor::loadAsset()
+{
+ // derived from LLPreviewNotecard::loadAsset
+
+ // TODO: see commented out "editor" references and make them do something appropriate to the UI
+
+ // request the asset.
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+
+ bool fail = false;
+
+ if (item)
+ {
+ LLPermissions perm(item->getPermissions());
+ bool allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+
+ setCanSaveAs(allow_copy);
+ setMaterialName(item->getName());
+
+ {
+ mAssetID = item->getAssetUUID();
+ if (mAssetID.isNull())
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ loadDefaults();
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ }
+ else
+ {
+ LLHost source_sim = LLHost();
+ LLSD* user_data = new LLSD();
+
+ if (mNotecardInventoryID.notNull())
+ {
+ user_data->with("objectid", mNotecardObjectID).with("notecardid", mNotecardInventoryID);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && objectp->getRegion())
+ {
+ source_sim = objectp->getRegion()->getHost();
+ }
+ else
+ {
+ // The object that we're trying to look at disappeared, bail.
+ LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL;
+ mAssetID.setNull();
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ return;
+ }
+ user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID);
+ }
+ else
+ {
+ user_data = new LLSD(mItemUUID);
+ }
+
+ setEnableEditing(false); // wait for it to load
+
+ gAssetStorage->getInvItemAsset(source_sim,
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getPermissions().getOwner(),
+ mObjectUUID,
+ item->getUUID(),
+ item->getAssetUUID(),
+ item->getType(),
+ &onLoadComplete,
+ (void*)user_data,
+ TRUE);
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ }
+ }
+ }
+ else if (mObjectUUID.notNull() && mItemUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty()))
+ {
+ // It's a material in object's inventory and we failed to get it because inventory is not up to date.
+ // Subscribe for callback and retry at inventoryChanged()
+ registerVOInventoryListener(objectp, NULL); //removes previous listener
+
+ if (objectp->isInventoryDirty())
+ {
+ objectp->requestInventory();
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+
+ if (fail)
+ {
+ /*editor->setText(LLStringUtil::null);
+ editor->makePristine();
+ editor->setEnabled(TRUE);*/
+ // Don't set asset status here; we may not have set the item id yet
+ // (e.g. when this gets called initially)
+ //mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+}
+
+// static
+void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status)
+{
+ LL_INFOS() << "LLMaterialEditor::onLoadComplete()" << LL_ENDL;
+ LLSD* floater_key = (LLSD*)user_data;
+ LLMaterialEditor* editor = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", *floater_key);
+ if (editor)
+ {
+ if (0 == status)
+ {
+ LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
+
+ S32 file_length = file.getSize();
+
+ std::vector<char> buffer(file_length + 1);
+ file.read((U8*)&buffer[0], file_length);
+
+ editor->decodeAsset(buffer);
+
+ BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem());
+ BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID());
+ editor->setEnableEditing(allow_modify && !source_library);
+ editor->resetUnsavedChanges();
+ editor->mAssetStatus = PREVIEW_ASSET_LOADED;
+ editor->setEnabled(true); // ready for use
+ }
+ else
+ {
+ if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ LLNotificationsUtil::add("MaterialMissing");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ LLNotificationsUtil::add("MaterialNoPermissions");
+ }
+ else
+ {
+ LLNotificationsUtil::add("UnableToLoadMaterial");
+ }
+ editor->setEnableEditing(false);
+
+ LL_WARNS() << "Problem loading material: " << status << LL_ENDL;
+ editor->mAssetStatus = PREVIEW_ASSET_ERROR;
+ }
+ }
+ delete floater_key;
+}
+
+void LLMaterialEditor::inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data)
+{
+ removeVOInventoryListener();
+ loadAsset();
+}
+
+
+void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb)
+{
+ if (asset_id.isNull()
+ || img == nullptr
+ || img->getDataSize() == 0)
+ {
+ return;
+ }
+
+ // copy image bytes into string
+ std::string buffer;
+ buffer.assign((const char*) img->getData(), img->getDataSize());
+
+ U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+
+
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewBufferedResourceUploadInfo>(
+ buffer,
+ asset_id,
+ name,
+ name,
+ 0,
+ LLFolderType::FT_TEXTURE,
+ LLInventoryType::IT_TEXTURE,
+ LLAssetType::AT_TEXTURE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost,
+ false,
+ cb));
+
+ upload_new_resource(uploadInfo);
+}
+
+S32 LLMaterialEditor::saveTextures()
+{
+ S32 work_count = 0;
+ LLSD key = getKey(); // must be locally declared for lambda's capture to work
+ if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mBaseColorJ2C, mBaseColorName, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setBaseColorId(newAssetId);
+ }
+ else
+ {
+ // To make sure that we won't retry (some failures can cb immediately)
+ me->setBaseColorId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+ if (mNormalTextureUploadId == getNormalId() && mNormalTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mNormalJ2C, mNormalName, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setNormalId(newAssetId);
+ }
+ else
+ {
+ me->setNormalId(LLUUID::null);
+ }
+ me->setNormalId(newAssetId);
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+ if (mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mMetallicRoughnessJ2C, mMetallicRoughnessName, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setMetallicRoughnessId(newAssetId);
+ }
+ else
+ {
+ me->setMetallicRoughnessId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+
+ if (mEmissiveTextureUploadId == getEmissiveId() && mEmissiveTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+ saveTexture(mEmissiveJ2C, mEmissiveName, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(key));
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setEmissiveId(newAssetId);
+ }
+ else
+ {
+ me->setEmissiveId(LLUUID::null);
+ }
+ me->mUploadingTexturesCount--;
+
+ // try saving
+ me->saveIfNeeded();
+ }
+ });
+ }
+
+ // discard upload buffers once textures have been saved
+ clearTextures();
+
+ // asset storage can callback immediately, causing a decrease
+ // of mUploadingTexturesCount, report amount of work scheduled
+ // not amount of work remaining
+ return work_count;
+}
+
+void LLMaterialEditor::clearTextures()
+{
+ mBaseColorJ2C = nullptr;
+ mNormalJ2C = nullptr;
+ mEmissiveJ2C = nullptr;
+ mMetallicRoughnessJ2C = nullptr;
+
+ mBaseColorFetched = nullptr;
+ mNormalFetched = nullptr;
+ mMetallicRoughnessFetched = nullptr;
+ mEmissiveFetched = nullptr;
+
+ mBaseColorTextureUploadId.setNull();
+ mNormalTextureUploadId.setNull();
+ mMetallicTextureUploadId.setNull();
+ mEmissiveTextureUploadId.setNull();
+}
+
+void LLMaterialEditor::loadDefaults()
+{
+ tinygltf::Model model_in;
+ model_in.materials.resize(1);
+ setFromGltfModel(model_in, 0, true);
+}
+
+void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ httpOpts->setFollowRedirects(true);
+
+ LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Failed to modify material." << LL_ENDL;
+ }
+ else if (!result["success"].asBoolean())
+ {
+ LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
new file mode 100644
index 0000000000..040dbe99da
--- /dev/null
+++ b/indra/newview/llmaterialeditor.h
@@ -0,0 +1,291 @@
+/**
+ * @file llmaterialeditor.h
+ * @brief LLMaterialEditor class header file
+ *
+ * $LicenseInfo:firstyear=2022&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$
+ */
+
+#pragma once
+
+#include "llpreview.h"
+#include "llvoinventorylistener.h"
+#include "llimagej2c.h"
+#include "llviewertexture.h"
+
+class LLTextureCtrl;
+class LLGLTFMaterial;
+class LLButton;
+class LLComboBox;
+class LLTextBox;
+
+namespace tinygltf
+{
+ class Model;
+}
+
+// todo: Consider making into a notification or just merging with
+// presets. Layout is identical to camera/graphics presets so there
+// is no point in having multiple separate xmls and classes.
+class LLFloaterComboOptions : public LLFloater
+{
+public:
+ typedef std::function<void(const std::string&, S32)> combo_callback;
+ LLFloaterComboOptions();
+
+ virtual ~LLFloaterComboOptions();
+ /*virtual*/ BOOL postBuild();
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options);
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options);
+
+private:
+ void onConfirm();
+ void onCancel();
+
+protected:
+ combo_callback mCallback;
+
+ LLButton *mConfirmButton;
+ LLButton *mCancelButton;
+ LLComboBox *mComboOptions;
+ LLTextBox *mComboText;
+};
+
+class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
+{
+public:
+ LLMaterialEditor(const LLSD& key);
+
+ bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
+
+ void setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index);
+
+ // open a file dialog and select a gltf/glb file for import
+ static void importMaterial();
+
+ // for live preview, apply current material to currently selected object
+ void applyToSelection();
+
+ void getGLTFMaterial(LLGLTFMaterial* mat);
+
+ void loadAsset() override;
+ // @index if -1 and file contains more than one material,
+ // will promt to select specific one
+ static void loadMaterialFromFile(const std::string& filename, S32 index = -1);
+
+ void onSelectionChanged(); // // live overrides selection changes
+ void saveLiveValues(); // for restoration on cancel
+ static void loadLive();
+ static void loadObjectSave();
+
+ static void loadFromGLTFMaterial(LLUUID &asset_id);
+
+ static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status);
+
+ void inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data) override;
+
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> upload_callback_f;
+ void saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb);
+
+ // save textures to inventory if needed
+ // returns amount of scheduled uploads
+ S32 saveTextures();
+ void clearTextures();
+
+ void onClickSave();
+
+ // get a dump of the json representation of the current state of the editor UI in GLTF format
+ std::string getGLTFJson(bool prettyprint = true);
+
+ void getGLBData(std::vector<U8>& data);
+
+ void getGLTFModel(tinygltf::Model& model);
+
+ std::string getEncodedAsset();
+
+ bool decodeAsset(const std::vector<char>& buffer);
+
+ bool saveIfNeeded();
+ static bool saveToInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id);
+
+ static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
+
+ static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
+
+ static void finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes);
+
+ void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null);
+
+ void onClickSaveAs();
+ void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response);
+ void onClickCancel();
+ void onCancelMsgCallback(const LLSD& notification, const LLSD& response);
+
+ // llpreview
+ void setObjectID(const LLUUID& object_id) override;
+ void setAuxItem(const LLInventoryItem* item) override;
+
+ // llpanel
+ BOOL postBuild() override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+
+ void onClose(bool app_quitting) override;
+
+ LLUUID getBaseColorId();
+ void setBaseColorId(const LLUUID& id);
+ void setBaseColorUploadId(const LLUUID& id);
+
+ LLColor4 getBaseColor();
+
+ // sets both base color and transparency
+ void setBaseColor(const LLColor4& color);
+
+ F32 getTransparency();
+ void setTransparency(F32 transparency);
+
+ std::string getAlphaMode();
+ void setAlphaMode(const std::string& alpha_mode);
+
+ F32 getAlphaCutoff();
+ void setAlphaCutoff(F32 alpha_cutoff);
+
+ void setMaterialName(const std::string &name);
+
+ LLUUID getMetallicRoughnessId();
+ void setMetallicRoughnessId(const LLUUID& id);
+ void setMetallicRoughnessUploadId(const LLUUID& id);
+
+ F32 getMetalnessFactor();
+ void setMetalnessFactor(F32 factor);
+
+ F32 getRoughnessFactor();
+ void setRoughnessFactor(F32 factor);
+
+ LLUUID getEmissiveId();
+ void setEmissiveId(const LLUUID& id);
+ void setEmissiveUploadId(const LLUUID& id);
+
+ LLColor4 getEmissiveColor();
+ void setEmissiveColor(const LLColor4& color);
+
+ LLUUID getNormalId();
+ void setNormalId(const LLUUID& id);
+ void setNormalUploadId(const LLUUID& id);
+
+ bool getDoubleSided();
+ void setDoubleSided(bool double_sided);
+
+ void setCanSaveAs(bool value);
+ void setCanSave(bool value);
+ void setEnableEditing(bool can_modify);
+
+ void onCommitBaseColorTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data);
+ void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data);
+
+ // initialize the UI from a default GLTF material
+ void loadDefaults();
+
+ void modifyMaterialCoro(std::string cap_url, LLSD overrides);
+
+ U32 getUnsavedChangesFlags() { return mUnsavedChanges; }
+
+private:
+ void setFromGLTFMaterial(LLGLTFMaterial* mat);
+ bool setFromSelection();
+
+ void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index);
+
+ friend class LLMaterialFilePicker;
+
+ LLUUID mAssetID;
+
+ LLTextureCtrl* mBaseColorTextureCtrl;
+ LLTextureCtrl* mMetallicTextureCtrl;
+ LLTextureCtrl* mEmissiveTextureCtrl;
+ LLTextureCtrl* mNormalTextureCtrl;
+
+ // 'Default' texture, unless it's null or from inventory is the one with the fee
+ LLUUID mBaseColorTextureUploadId;
+ LLUUID mMetallicTextureUploadId;
+ LLUUID mEmissiveTextureUploadId;
+ LLUUID mNormalTextureUploadId;
+
+ // last known name of each texture
+ std::string mBaseColorName;
+ std::string mNormalName;
+ std::string mMetallicRoughnessName;
+ std::string mEmissiveName;
+
+ // keep pointers to fetched textures or viewer will remove them
+ // if user temporary selects something else with 'apply now'
+ LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
+ LLPointer<LLViewerFetchedTexture> mNormalFetched;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessFetched;
+ LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
+
+ // J2C versions of packed buffers for uploading
+ LLPointer<LLImageJ2C> mBaseColorJ2C;
+ LLPointer<LLImageJ2C> mNormalJ2C;
+ LLPointer<LLImageJ2C> mMetallicRoughnessJ2C;
+ LLPointer<LLImageJ2C> mEmissiveJ2C;
+
+ // utility function for converting image uri into a texture name
+ const std::string getImageNameFromUri(std::string image_uri, const std::string texture_type);
+
+ // utility function for building a description of the imported material
+ // based on what we know about it.
+ const std::string buildMaterialDescription();
+
+ void resetUnsavedChanges();
+ void markChangesUnsaved(U32 dirty_flag);
+
+ U32 mUnsavedChanges; // flags to indicate individual changed parameters
+ S32 mUploadingTexturesCount;
+ S32 mExpectedUploadCost;
+ std::string mMaterialNameShort;
+ std::string mMaterialName;
+
+ // if true, this instance is live instance editing overrides
+ bool mIsOverride = false;
+ // local id, texture ids per face for object overrides
+ // for "cancel" support
+ std::map<U32, uuid_vec_t> mObjectOverridesSavedValues;
+ boost::signals2::connection mSelectionUpdateSlot;
+};
+
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 142977e939..d3b981e205 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
if (matchPred(*it))
{
(*it)->markDead();
- // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
- c.erase(it++);
+ it = c.erase(it);
}
else
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 6fa71e130e..5a6010d5e4 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheBytesHeaders = 0;
+U32 LLMeshRepository::sCacheBytesSkins = 0;
+U32 LLMeshRepository::sCacheBytesDecomps = 0;
U32 LLMeshRepository::sCacheReads = 0;
U32 LLMeshRepository::sCacheWrites = 0;
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
@@ -1874,6 +1877,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
+ LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -2051,17 +2055,6 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
if (volume->unpackVolumeFaces(stream, data_size))
{
- //load volume faces into decomposition buffer
- S32 vertex_count = 0;
- S32 index_count = 0;
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- vertex_count += face.mNumVertices;
- index_count += face.mNumIndices;
- }
-
d->mPhysicsShapeMesh.clear();
std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions;
@@ -3013,27 +3006,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
return -1;
}
-void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
-{
- mThread->mMeshHeader[data.mUUID] = header;
-
- // we cache the mesh for default parameters
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (data.mModel[i].notNull())
- {
- LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
- volume->copyVolumeFaces(data.mModel[i]);
- volume->setMeshAssetLoaded(TRUE);
- }
- }
-
-}
-
// Handle failed or successful requests for mesh assets.
//
// Support for 200 responses was added for several reasons. One,
@@ -3951,6 +3923,8 @@ void LLMeshRepository::notifyLoadedMeshes()
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
{
mSkinMap[info.mMeshID] = info;
+ // Alternative: We can get skin size from header
+ sCacheBytesSkins += info.sizeBytes();
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
if (iter != mLoadingSkins.end())
@@ -3974,10 +3948,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
mLoadingDecompositions.erase(decomp->mMeshID);
+ sCacheBytesDecomps += decomp->sizeBytes();
}
else
{ //merge decomp with existing entry
+ sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
+ sCacheBytesDecomps += iter->second->sizeBytes();
+
mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 5459bbb4af..6fe4ea5514 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -552,6 +552,9 @@ public:
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheBytesHeaders;
+ static U32 sCacheBytesSkins;
+ static U32 sCacheBytesDecomps;
static U32 sCacheReads;
static U32 sCacheWrites;
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
@@ -641,8 +644,6 @@ public:
std::queue<LLUUID> mPendingPhysicsShapeRequests;
U32 mMeshThreadCount;
-
- void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
LLMeshRepoThread* mThread;
std::vector<LLMeshUploadThread*> mUploads;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 859d987fc3..914528c7ce 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -30,6 +30,7 @@
#include "llmodelloader.h"
#include "lldaeloader.h"
+#include "llgltfloader.h"
#include "llfloatermodelpreview.h"
#include "llagent.h"
@@ -86,6 +87,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);
static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);
static const F32 PREVIEW_DEG_POINT_SIZE(8.f);
static const F32 PREVIEW_ZOOM_LIMIT(10.f);
+static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
@@ -432,6 +434,20 @@ void LLModelPreview::rebuildUploadData()
LLFloaterModelPreview::addStringToLog(out, false);
}
}
+ if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS))
+ {
+ // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition.
+ // That's ok, but might not what they wanted. Use default_physics_shape if found.
+ std::ostringstream out;
+ out << "No physics model specified for " << instance.mLabel;
+ if (mDefaultPhysicsShapeP)
+ {
+ out << " - using: " << DEFAULT_PHYSICS_MESH_NAME;
+ lod_model = mDefaultPhysicsShapeP;
+ }
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default.
+ }
if (lod_model)
{
@@ -732,20 +748,41 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
std::map<std::string, std::string> joint_alias_map;
getJointAliases(joint_alias_map);
- mModelLoader = new LLDAELoader(
- filename,
- lod,
- &LLModelPreview::loadedCallback,
- &LLModelPreview::lookupJointByName,
- &LLModelPreview::loadTextures,
- &LLModelPreview::stateChangedCallback,
- this,
- mJointTransformMap,
- mJointsFromNode,
- joint_alias_map,
- LLSkinningUtil::getMaxJointCount(),
- gSavedSettings.getU32("ImporterModelLimit"),
- gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ // three possible file extensions, .dae .gltf .glb
+ // check for .dae and if not then assume one of the .gl??
+ if (std::string::npos != filename.rfind(".dae"))
+ {
+ mModelLoader = new LLDAELoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"),
+ gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ }
+ else
+ {
+ mModelLoader = new LLGLTFLoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"));
+ }
if (force_disable_slm)
{
@@ -816,8 +853,10 @@ void LLModelPreview::clearIncompatible(S32 lod)
// at this point we don't care about sub-models,
// different amount of sub-models means face count mismatch, not incompatibility
U32 lod_size = countRootModels(mModel[lod]);
+ bool replaced_base_model = (lod == LLModel::LOD_HIGH);
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
- { //clear out any entries that aren't compatible with this model
+ {
+ // Clear out any entries that aren't compatible with this model
if (i != lod)
{
if (countRootModels(mModel[i]) != lod_size)
@@ -831,9 +870,47 @@ void LLModelPreview::clearIncompatible(S32 lod)
mBaseModel = mModel[lod];
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
+ replaced_base_model = true;
+ }
+ }
+ }
+ }
+
+ if (replaced_base_model && !mGenLOD)
+ {
+ // In case base was replaced, we might need to restart generation
+
+ // Check if already started
+ bool subscribe_for_generation = mLodsQuery.empty();
+
+ // Remove previously scheduled work
+ mLodsQuery.clear();
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (!fmp) return;
+
+ // Schedule new work
+ for (S32 i = LLModel::LOD_HIGH; i >= 0; --i)
+ {
+ if (mModel[i].empty())
+ {
+ // Base model was replaced, regenerate this lod if applicable
+ LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[i]);
+ if (!lod_combo) return;
+
+ S32 lod_mode = lod_combo->getCurrentIndex();
+ if (lod_mode != LOD_FROM_FILE)
+ {
+ mLodsQuery.push_back(i);
}
}
}
+
+ // Subscribe if we have pending work and not subscribed yet
+ if (!mLodsQuery.empty() && subscribe_for_generation)
+ {
+ doOnIdleRepeating(lodQueryCallback);
+ }
}
}
@@ -994,6 +1071,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
}
else
{
+ if (loaded_lod == LLModel::LOD_PHYSICS)
+ { // Explicitly loading physics. See if there is a default mesh.
+ LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own.
+ mDefaultPhysicsShapeP = nullptr;
+ FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform);
+ mWarnOfUnmatchedPhyicsMeshes = true;
+ }
BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
@@ -1064,7 +1148,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
-
mModel[loaded_lod][idx]->mLabel = name;
}
}
@@ -1221,8 +1304,9 @@ void LLModelPreview::restoreNormals()
// Runs per object, but likely it is a better way to run per model+submodels
// returns a ratio of base model indices to resulting indices
// returns -1 in case of failure
-F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
+ // I. Weld faces together
// Figure out buffer size
S32 size_indices = 0;
S32 size_vertices = 0;
@@ -1245,7 +1329,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// extra space for normals and text coords
S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF;
- LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* combined_normals = combined_positions + size_vertices;
LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices);
@@ -1257,20 +1341,21 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
- // vertices
+ // Vertices
S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a);
LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes);
- // normals
+ // Normals
LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes);
- // tex coords
+ // Tex coords
copy_bytes = face.mNumVertices * sizeof(LLVector2);
memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes);
combined_positions_shift += face.mNumVertices;
- // indices, sadly can't do dumb memcpy for indices, need to adjust each value
+ // Indices
+ // Sadly can't do dumb memcpy for indices, need to adjust each value
for (S32 i = 0; i < face.mNumIndices; ++i)
{
U16 idx = face.mIndices[i];
@@ -1281,10 +1366,42 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
indices_idx_shift += face.mNumVertices;
}
- // Now that we have buffers, optimize
+ // II. Generate a shadow buffer if nessesary.
+ // Welds together vertices if possible
+
+ U32* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ // Note: simplifySloppy can affect UVs significantly.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ // strip normals, reflections should restore relatively correctly
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, combined_tex_coords, size_vertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ // strip uvs, can heavily affect textures
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, NULL, size_vertices);
+ }
+
+ U32* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = combined_indices;
+ }
+
+ // III. Simplify
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1294,40 +1411,45 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplifyU32(
+
+ size_new_indices = LLMeshOptimizer::simplifyU32(
output_indices,
- combined_indices,
+ source_indices,
size_indices,
combined_positions,
size_vertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices << LL_ENDL;
}
- if (new_indices < 3)
+ // free unused buffers
+ ll_aligned_free_32(combined_indices);
+ ll_aligned_free_32(shadow_indices);
+ combined_indices = NULL;
+ shadow_indices = NULL;
+
+ if (size_new_indices < 3)
{
// Model should have at least one visible triangle
ll_aligned_free<64>(combined_positions);
ll_aligned_free_32(output_indices);
- ll_aligned_free_32(combined_indices);
return -1;
}
- // repack back into individual faces
+ // IV. Repack back into individual faces
- LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* buffer_normals = buffer_positions + size_vertices;
LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices);
S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
@@ -1356,7 +1478,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
// Copy relevant indices and vertices
- for (S32 i = 0; i < new_indices; ++i)
+ for (S32 i = 0; i < size_new_indices; ++i)
{
U32 idx = output_indices[i];
@@ -1379,19 +1501,19 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
LL_WARNS() << "Over triangle limit. Failed to optimize in 'per object' mode, falling back to per face variant for"
<< " model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
// U16 vertices overflow shouldn't happen, but just in case
- new_indices = 0;
+ size_new_indices = 0;
valid_faces = 0;
for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
- genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, false);
+ genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, simplification_mode);
const LLVolumeFace &face = target_model->getVolumeFace(face_idx);
- new_indices += face.mNumIndices;
+ size_new_indices += face.mNumIndices;
if (face.mNumIndices >= 3)
{
valid_faces++;
@@ -1399,7 +1521,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
if (valid_faces)
{
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
else
{
@@ -1448,7 +1570,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
new_face.resizeIndices(buf_indices_copied);
new_face.resizeVertices(buf_positions_copied);
-
+ new_face.allocateTangents(buf_positions_copied);
S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size);
@@ -1469,18 +1591,17 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
ll_aligned_free<64>(buffer_positions);
ll_aligned_free_32(output_indices);
ll_aligned_free_16(buffer_indices);
- ll_aligned_free_32(combined_indices);
- if (new_indices < 3 || valid_faces == 0)
+ if (size_new_indices < 3 || valid_faces == 0)
{
// Model should have at least one visible triangle
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
-F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
S32 size_indices = face.mNumIndices;
@@ -1488,14 +1609,40 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
return -1;
}
- // todo: do not allocate per each face, add one large buffer somewhere
- // faces have limited amount of indices
+
S32 size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
- U16* output = (U16*)ll_aligned_malloc_16(size);
+ U16* output_indices = (U16*)ll_aligned_malloc_16(size);
+
+ U16* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, face.mTexCoords, face.mNumVertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, NULL, face.mNumVertices);
+ }
+ // Don't run ShadowIndexBuffer for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+
+ U16* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = face.mIndices;
+ }
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1505,25 +1652,25 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplify(
- output,
- face.mIndices,
+
+ size_new_indices = LLMeshOptimizer::simplify(
+ output_indices,
+ source_indices,
size_indices,
face.mPositions,
face.mNumVertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for face " << face_idx
<< " of model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
@@ -1534,10 +1681,9 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
// Copy old values
new_face = face;
-
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
- if (!sloppy)
+ if (simplification_mode != MESH_OPTIMIZER_NO_TOPOLOGY)
{
// meshopt_optimizeSloppy() can optimize triangles away even if target_indices is > 2,
// but optimize() isn't supposed to
@@ -1561,23 +1707,24 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
else
{
// Assign new values
- new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output
- S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size);
+ new_face.resizeIndices(size_new_indices); // will wipe out mIndices, so new_face can't substitute output
+ S32 idx_size = (size_new_indices * sizeof(U16) + 0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output_indices, idx_size);
- // clear unused values
+ // Clear unused values
new_face.optimize();
}
- ll_aligned_free_16(output);
+ ll_aligned_free_16(output_indices);
+ ll_aligned_free_16(shadow_indices);
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
// At least one triangle is needed
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 decimation, bool enforce_tri_limit)
@@ -1707,20 +1854,31 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
LLModel* target_model = mModel[lod][mdl_idx];
+ // carry over normalized transform into simplified model
+ for (int i = 0; i < base->getNumVolumeFaces(); ++i)
+ {
+ LLVolumeFace& src = base->getVolumeFace(i);
+ LLVolumeFace& dst = target_model->getVolumeFace(i);
+ dst.mNormalizedScale = src.mNormalizedScale;
+ }
+
S32 model_meshopt_mode = meshopt_mode;
// Ideally this should run not per model,
// but combine all submodels with origin model as well
- if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE)
+ if (model_meshopt_mode == MESH_OPTIMIZER_PRECISE)
{
- // Run meshoptimizer for each model/object, up to 8 faces in one model.
-
- // Ideally this should run not per model,
- // but combine all submodels with origin model as well
- F32 res = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
- if (res < 0)
+ // Run meshoptimizer for each face
+ for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- target_model->copyVolumeFaces(base);
+ F32 res = genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+ if (res < 0)
+ {
+ // Mesh optimizer failed and returned an invalid model
+ const LLVolumeFace &face = base->getVolumeFace(face_idx);
+ LLVolumeFace &new_face = target_model->getVolumeFace(face_idx);
+ new_face = face;
+ }
}
}
@@ -1729,19 +1887,29 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Run meshoptimizer for each face
for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true) < 0)
+ if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0)
{
// Sloppy failed and returned an invalid model
- genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
+ genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
}
}
if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)
{
- // Switches between 'combine' method and 'sloppy' based on combine's result.
- F32 allowed_ratio_drift = 2.f;
- F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ // Remove progressively more data if we can't reach the target.
+ F32 allowed_ratio_drift = 1.8f;
+ F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_NORMALS);
+ }
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_UVS);
+ }
if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
{
@@ -1749,10 +1917,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Sloppy variant can fail entirely and has issues with precision,
// so code needs to do multiple attempts with different decimators.
// Todo: this is a bit of a mess, needs to be refined and improved
+
F32 last_working_decimator = 0.f;
F32 last_working_ratio = F32_MAX;
- F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
if (sloppy_ratio > 0)
{
@@ -1775,13 +1944,13 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// side due to overal lack of precision, and we don't need an ideal result, which
// likely does not exist, just a better one, so a partial correction is enough.
F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2;
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio)
{
// Compensation didn't work, return back to previous decimator
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (sloppy_ratio < 0)
@@ -1814,7 +1983,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
&& sloppy_decimator > precise_ratio
&& sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case
{
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
sloppy_decimator = sloppy_decimator / sloppy_decimation_step;
}
}
@@ -1834,7 +2003,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
else
{
// Fallback to normal method
- precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
LL_INFOS() << "Model " << target_model->getName()
@@ -2562,8 +2731,6 @@ void LLModelPreview::clearBuffers()
void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
- U32 tri_count = 0;
- U32 vertex_count = 0;
U32 mesh_count = 0;
@@ -2596,7 +2763,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
continue;
}
- LLModel* base_mdl = *base_iter;
base_iter++;
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2671,7 +2837,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
//find closest weight to vf.mVertices[i].mPosition
LLVector3 pos(vf.mPositions[i].getF32ptr());
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0, 0, 0, 0);
@@ -2699,10 +2865,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mVertexBuffer[lod][mdl].push_back(vb);
- vertex_count += num_vertices;
- tri_count += num_indices / 3;
++mesh_count;
-
}
}
}
@@ -2798,6 +2961,20 @@ void LLModelPreview::loadedCallback(
{
pPreview->lookupLODModelFiles(lod);
}
+
+ const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
+ if (avatarp) { // set up ground plane for possible rendering
+ const LLVector3 root_pos = avatarp->mRoot->getPosition();
+ const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
+ const LLVector4a min = ext[0], max = ext[1];
+ const F32 center = (max[2] - min[2]) * 0.5f;
+ const F32 ground = root_pos[2] - center;
+ auto plane = pPreview->mGroundPlane;
+ plane[0] = {min[0], min[1], ground};
+ plane[1] = {max[0], min[1], ground};
+ plane[2] = {max[0], max[1], ground};
+ plane[3] = {min[0], max[1], ground};
+ }
}
}
@@ -3005,6 +3182,9 @@ BOOL LLModelPreview::render()
// (note: all these UI updates need to be somewhere that is not render)
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
+ upload_skin = true;
+ skin_weight = true;
+ mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
@@ -3609,6 +3789,7 @@ BOOL LLModelPreview::render()
{
getPreviewAvatar()->renderBones();
}
+ renderGroundPlane(mPelvisZOffset);
if (shader)
{
shader->bind();
@@ -3630,6 +3811,28 @@ BOOL LLModelPreview::render()
return TRUE;
}
+void LLModelPreview::renderGroundPlane(float z_offset)
+{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render
+
+ gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+ gGL.vertex3fv(mGroundPlane[1].mV);
+
+ gGL.vertex3fv(mGroundPlane[1].mV);
+ gGL.vertex3fv(mGroundPlane[2].mV);
+
+ gGL.vertex3fv(mGroundPlane[2].mV);
+ gGL.vertex3fv(mGroundPlane[3].mV);
+
+ gGL.vertex3fv(mGroundPlane[3].mV);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+
+ gGL.end();
+}
+
+
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
@@ -3745,7 +3948,7 @@ bool LLModelPreview::lodQueryCallback()
}
// return false to continue cycle
- return false;
+ return preview->mLodsQuery.empty();
}
}
// nothing to process
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 9e32215e6a..df7320768c 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -125,7 +125,7 @@ public:
{
LOD_FROM_FILE = 0,
MESH_OPTIMIZER_AUTO, // automatically selects method based on model or face
- MESH_OPTIMIZER_COMBINE, // combines faces into a single model, simplifies, then splits back into faces
+ MESH_OPTIMIZER_PRECISE, // combines faces into a single model, simplifies, then splits back into faces
MESH_OPTIMIZER_SLOPPY, // uses sloppy method, works per face
USE_LOD_ABOVE,
} eLoDMode;
@@ -224,14 +224,39 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ LLVector3 mGroundPlane[4];
+ void renderGroundPlane(float z_offset = 0.0f);
+ /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh.
+ /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when
+ /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()).
+ ///
+ /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When
+ /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when
+ /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot.
+ /// When there are multiple meshes in each file, they are matched by name or order, and some meshes
+ /// are broken up by limitations into multiple objects, and thus there can be mismatches.)
+ bool mWarnOfUnmatchedPhyicsMeshes{false};
+ /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified.
+ /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME.
+ /// It is reset when such a name is not found, and when resetting the modelpreview.
+ /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true.
+ LLModel* mDefaultPhysicsShapeP{};
+
+ typedef enum
+ {
+ MESH_OPTIMIZER_FULL,
+ MESH_OPTIMIZER_NO_NORMALS,
+ MESH_OPTIMIZER_NO_UVS,
+ MESH_OPTIMIZER_NO_TOPOLOGY,
+ } eSimplificationMode;
// Merges faces into single mesh, simplifies using mesh optimizer,
// then splits back into faces.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
// Simplifies specified face using mesh optimizer.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
protected:
friend class LLModelLoader;
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4a8ef53a8b..bf00d77dea 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
void LLMuteList::updateAdd(const LLMute& mute)
{
- // External mutes (e.g. Avaline callers) are local only, don't send them to the server.
+ // External mutes are local only, don't send them to the server.
if (mute.mType == LLMute::EXTERNAL)
{
return;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 5215126789..8058faa5c7 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+// virtual
+BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
+ LLFloater* floater = gFloaterView->getParentFloater(this);
+ if (floater && floater->isFrontmost() && hit_item)
+ {
+ if(hit_item->isGroup())
+ {
+ ContextMenuType prev_menu = getContextMenuType();
+ setContextMenu(MENU_GROUP);
+ BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+ setContextMenu(prev_menu);
+ return handled;
+ }
+ }
+ return LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+}
+
// public
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ef0be135e6..5dd5da5892 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -170,6 +170,7 @@ public:
/*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 19dbbeb60e..f5ee1171d9 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection()
if(value.has("AssetUUID"))
{
-
gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
- mSaveToLocationHistory = true;
+ // user teleported by manually inputting inventory landmark's name
+ mSaveToLocationHistory = false;
return;
}
else
@@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
+ LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
}
void LLNavigationBar::clearHistoryCache()
@@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight()
{
return mDefaultFpRect.getHeight();
}
+
+bool LLNavigationBar::isRebakeNavMeshAvailable()
+{
+ return mCmbLocation->isNavMeshDirty();
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 646911a62c..11c671294a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -102,6 +102,8 @@ public:
int getDefNavBarHeight();
int getDefFavBarHeight();
+
+ bool isRebakeNavMeshAvailable();
private:
// the distance between navigation panel and favorites panel in pixels
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1240ce7c0f..b34be80b07 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)
mPopupMenu(NULL)
{
mScale = gSavedSettings.getF32("MiniMapScale");
+ if (gAgent.isFirstLogin())
+ {
+ // *HACK: On first run, set this to false for new users, otherwise the
+ // default is true to maintain consistent experience for existing
+ // users.
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
}
@@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -158,18 +183,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -216,7 +255,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -225,8 +265,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -249,6 +289,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -310,8 +351,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -327,6 +368,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -451,41 +499,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
+ if (gDisconnected)
+ {
+ return false;
+ }
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..fe1aca65a9 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -62,9 +62,12 @@ protected:
public:
virtual ~LLNetMap();
- static const F32 MAP_SCALE_MIN;
- static const F32 MAP_SCALE_MID;
- static const F32 MAP_SCALE_MAX;
+ static const F32 MAP_SCALE_MIN;
+ static const F32 MAP_SCALE_FAR;
+ static const F32 MAP_SCALE_MEDIUM;
+ static const F32 MAP_SCALE_CLOSE;
+ static const F32 MAP_SCALE_VERY_CLOSE;
+ static const F32 MAP_SCALE_MAX;
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -79,8 +82,17 @@ public:
/*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- void setScale( F32 scale );
- void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setScale(F32 scale);
+
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; }
+ void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; }
+ void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; }
+ void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; }
+ void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; }
+ void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; }
+ void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; }
+
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -94,11 +106,14 @@ private:
void drawTracking( const LLVector3d& pos_global,
const LLColor4& color,
BOOL draw_arrow = TRUE);
+ bool isMouseOnPopupMenu();
+ void updateAboutLandPopupButton();
BOOL handleToolTipAgent(const LLUUID& avatar_id);
static void showAvatarInspector(const LLUUID& avatar_id);
void createObjectImage();
+ F32 getScaleForName(std::string scale_name);
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
private:
@@ -112,11 +127,12 @@ private:
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
- bool mPanning; // map is being dragged
- LLVector2 mTargetPan;
- LLVector2 mCurPan;
- LLVector2 mStartPan; // pan offset at start of drag
- LLCoordGL mMouseDown; // pointer position at start of drag
+ bool mPanning; // map is being dragged
+ bool mCentering; // map is being re-centered around the agent
+ LLVector2 mCurPan;
+ LLVector2 mStartPan; // pan offset at start of drag
+ LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened
+ LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
@@ -125,14 +141,26 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- std::string mToolTipMsg;
+ std::string mToolTipMsg;
+ std::string mParcelNameMsg;
+ std::string mParcelSalePriceMsg;
+ std::string mParcelSaleAreaMsg;
+ std::string mParcelOwnerMsg;
+ std::string mRegionNameMsg;
+ std::string mToolTipHintMsg;
+ std::string mAltToolTipHintMsg;
public:
void setSelected(uuid_vec_t uuids) { gmSelected=uuids; };
private:
- void handleZoom(const LLSD& userdata);
- void handleStopTracking (const LLSD& userdata);
+ bool isZoomChecked(const LLSD& userdata);
+ void setZoom(const LLSD& userdata);
+ void handleStopTracking(const LLSD& userdata);
+ void activateCenterMap(const LLSD& userdata);
+ bool isMapOrientationChecked(const LLSD& userdata);
+ void setMapOrientation(const LLSD& userdata);
+ void popupShowAboutLand(const LLSD& userdata);
LLMenuGL* mPopupMenu;
uuid_vec_t gmSelected;
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4febb72c6c..d11b3b57f3 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1177,7 +1177,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
{
return;
}
- (new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false);
}
void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
@@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
texture_floaterp->setCanApply(false, true);
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 37ed4bc74c..ff33efe4aa 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&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$
*/
@@ -28,173 +28,127 @@
#include "llpanelavatar.h"
#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallingcard.h"
-#include "llcombobox.h"
-#include "lldateutil.h" // ageFromDate()
-#include "llimview.h"
-#include "llmenubutton.h"
-#include "llnotificationsutil.h"
-#include "llslurl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
+#include "llloadingindicator.h"
#include "lltooldraganddrop.h"
-#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llfloaterreg.h"
-#include "llnotificationsutil.h"
-#include "llviewermenu.h" // is_agent_mappable
-#include "llvoiceclient.h"
-#include "lltextbox.h"
-#include "lltrans.h"
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLDropTarget
-//
-// This handy class is a simple way to drop something on another
-// view. It handles drop events, always setting itself to the size of
-// its parent.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLDropTarget : public LLView
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUUID> agent_id;
- Params()
- : agent_id("agent_id")
- {
- changeDefault(mouse_opaque, false);
- changeDefault(follows.flags, FOLLOWS_ALL);
- }
- };
-
- LLDropTarget(const Params&);
- ~LLDropTarget();
-
- void doDrop(EDragAndDropType cargo_type, void* cargo_data);
-
- //
- // LLView functionality
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
-protected:
- LLUUID mAgentID;
-};
-
-LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
-: LLView(p),
- mAgentID(p.agent_id)
-{}
-LLDropTarget::~LLDropTarget()
+//////////////////////////////////////////////////////////////////////////
+// LLProfileDropTarget
+
+LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
{}
-void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
- LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
+ LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
}
-BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
+BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if(getParent())
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
- cargo_type, cargo_data, accept);
+ if (getParent())
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
+ cargo_type, cargo_data, accept);
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
+static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_target");
//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileTab
LLPanelProfileTab::LLPanelProfileTab()
: LLPanel()
, mAvatarId(LLUUID::null)
+, mLoadingState(PROFILE_INIT)
+, mSelfProfile(false)
{
}
LLPanelProfileTab::~LLPanelProfileTab()
{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
}
-void LLPanelProfileTab::setAvatarId(const LLUUID& id)
+void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
{
- if(id.notNull())
- {
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
- }
- mAvatarId = id;
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
- }
+ if (avatar_id.notNull())
+ {
+ mAvatarId = avatar_id;
+ mSelfProfile = (getAvatarId() == gAgentID);
+ }
}
void LLPanelProfileTab::onOpen(const LLSD& key)
{
- // Don't reset panel if we are opening it for same avatar.
- if(getAvatarId() != key.asUUID())
- {
- resetControls();
- resetData();
-
- scrollToTop();
- }
-
- // Update data even if we are viewing same avatar profile as some data might been changed.
- setAvatarId(key.asUUID());
- updateData();
- updateButtons();
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
+
+ setApplyProgress(true);
+}
+
+void LLPanelProfileTab::setLoaded()
+{
+ setApplyProgress(false);
+
+ mLoadingState = PROFILE_LOADED;
+}
+
+void LLPanelProfileTab::setApplyProgress(bool started)
+{
+ LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator");
+
+ if (indicator)
+ {
+ indicator->setVisible(started);
+
+ if (started)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ }
+
+ LLView* panel = findChild<LLView>("indicator_stack");
+ if (panel)
+ {
+ panel->setVisible(started);
+ }
}
-void LLPanelProfileTab::scrollToTop()
+LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
+ : LLPanelProfileTab()
{
- LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
- if (scrollContainer)
- scrollContainer->goToTop();
}
-void LLPanelProfileTab::onMapButtonClick()
+LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
{
- LLAvatarActions::showOnMap(getAvatarId());
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
}
-void LLPanelProfileTab::updateButtons()
+void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
{
- bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
-
- if(LLAvatarActions::isFriend(getAvatarId()))
- {
- getChildView("teleport")->setEnabled(is_buddy_online);
- }
- else
- {
- getChildView("teleport")->setEnabled(true);
- }
-
- bool enable_map_btn = (is_buddy_online &&
- is_agent_mappable(getAvatarId()))
- || gAgent.isGodlike();
- getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ }
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..f182660c8e 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.h
- * @brief LLPanelAvatar and related class definitions
+ * @brief Legacy profile panel base class
*
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2019, 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$
*/
@@ -29,80 +29,141 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
-#include "llvoiceclient.h"
#include "llavatarnamecache.h"
class LLComboBox;
class LLLineEditor;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLProfileDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLProfileDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUUID> agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+
+ LLProfileDropTarget(const Params&);
+ ~LLProfileDropTarget() {}
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
+
+protected:
+ LLUUID mAgentID;
+};
+
+
/**
* Base class for any Profile View.
*/
class LLPanelProfileTab
- : public LLPanel
- , public LLAvatarPropertiesObserver
+ : public LLPanel
{
public:
- /**
- * Sets avatar ID, sets panel as observer of avatar related info replies from server.
- */
- virtual void setAvatarId(const LLUUID& id);
-
- /**
- * Returns avatar ID.
- */
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sends update data request to server.
- */
- virtual void updateData() = 0;
-
- /**
- * Clears panel data if viewing avatar info for first time and sends update data request.
- */
- virtual void onOpen(const LLSD& key);
-
- /**
- * Profile tabs should close any opened panels here.
- *
- * Called from LLPanelProfile::onOpen() before opening new profile.
- * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
- * before new profile is displayed, otherwise new profile will
- * be hidden behind picture info panel.
- */
- virtual void onClosePanel() {}
-
- /**
- * Resets controls visibility, state, etc.
- */
- virtual void resetControls(){};
-
- /**
- * Clears all data received from server.
- */
- virtual void resetData(){};
-
- /*virtual*/ ~LLPanelProfileTab();
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() {};
+
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
+
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
+
+ /*virtual*/ ~LLPanelProfileTab();
protected:
- LLPanelProfileTab();
+ LLPanelProfileTab();
+
+ enum ELoadingState
+ {
+ PROFILE_INIT,
+ PROFILE_LOADING,
+ PROFILE_LOADED,
+ };
+
+
+ // mLoading: false: Initial state, can request
+ // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
+ // mLoaded: false: Initial state, show loading indicator
+ // true: Data recieved, which comes in a single message, hide indicator
+ ELoadingState getLoadingState() { return mLoadingState; }
+ virtual void setLoaded();
+ void setApplyProgress(bool started);
+
+ const bool getSelfProfile() const { return mSelfProfile; }
- /**
- * Scrolls panel to top when viewing avatar info for first time.
- */
- void scrollToTop();
+public:
+ void setIsLoading() { mLoadingState = PROFILE_LOADING; }
+ void resetLoading() { mLoadingState = PROFILE_INIT; }
- virtual void onMapButtonClick();
+ bool getStarted() { return mLoadingState != PROFILE_INIT; }
+ bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
- virtual void updateButtons();
+ virtual bool hasUnsavedChanges() { return false; }
+ virtual void commitUnsavedChanges() {}
private:
- LLUUID mAvatarId;
+ LLUUID mAvatarId;
+ ELoadingState mLoadingState;
+ bool mSelfProfile;
+};
+
+class LLPanelProfilePropertiesProcessorTab
+ : public LLPanelProfileTab
+ , public LLAvatarPropertiesObserver
+{
+public:
+ LLPanelProfilePropertiesProcessorTab();
+ ~LLPanelProfilePropertiesProcessorTab();
+
+ /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Processes data received from server via LLAvatarPropertiesObserver.
+ */
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 3322e8a3df..3a4fc613b7 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -232,7 +232,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
if (names.empty() || ids.empty()) return;
- LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
+ LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT);
LLMuteList::getInstance()->add(mute);
showPanelAndSelect(mute.mID);
}
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c0342eef4e..183000ceac 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.cpp
- * @brief LLPanelClassified class implementation
+ * @brief LLPanelClassifiedInfo class implementation
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -34,33 +34,21 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llcombobox.h"
#include "lltexturectrl.h"
-#include "lltexteditor.h"
-#include "llviewerparcelmgr.h"
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "lltrans.h"
#include "llscrollcontainer.h"
-#include "llstatusbar.h"
-#include "llviewertexture.h"
#include "llcorehttputil.h"
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
-
//static
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
+static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
// "classifiedclickthrough"
// strings[0] = classified_id
@@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
sAllPanels.remove(this);
}
-// static
-LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
-{
- LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
- panel->buildFromFile("panel_classified_info.xml");
- return panel;
-}
-
BOOL LLPanelClassifiedInfo::postBuild()
{
- childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
@@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
return TRUE;
}
-void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild<LLUICtrl>("creation_date")->setValue(date_str);
setInfoLoaded(true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
}
}
-void LLPanelClassifiedInfo::onExit()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
- gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-static const S32 CB_ITEM_MATURE = 0;
-static const S32 CB_ITEM_PG = 1;
-
-LLPanelClassifiedEdit::LLPanelClassifiedEdit()
- : LLPanelClassifiedInfo()
- , mIsNew(false)
- , mIsNewWithErrors(false)
- , mCanClose(false)
- , mPublishFloater(NULL)
-{
-}
-
-LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
-{
-}
-
-//static
-LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
-{
- LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
- panel->buildFromFile("panel_edit_classified.xml");
- return panel;
-}
-
-BOOL LLPanelClassifiedEdit::postBuild()
-{
- LLPanelClassifiedInfo::postBuild();
-
- LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
- edit_icon->setVisible(false);
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- LLComboBox* combobox = getChild<LLComboBox>( "category");
- LLClassifiedInfo::cat_map::iterator iter;
- for (iter = LLClassifiedInfo::sCategories.begin();
- iter != LLClassifiedInfo::sCategories.end();
- iter++)
- {
- combobox->add(LLTrans::getString(iter->second));
- }
-
- combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
-
- mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
-
- return TRUE;
-}
-
-void LLPanelClassifiedEdit::fillIn(const LLSD& key)
-{
- setAvatarId(gAgent.getID());
-
- if(key.isUndefined())
- {
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID snapshot_id = LLUUID::null;
- std::string desc;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(parcel)
- {
- desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
- getChild<LLUICtrl>("classified_desc")->setValue(desc);
- setSnapshotId(snapshot_id);
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
- // server will set valid parcel id
- setParcelId(LLUUID::null);
- }
- else
- {
- setClassifiedId(key["classified_id"]);
- setClassifiedName(key["name"]);
- setDescription(key["desc"]);
- setSnapshotId(key["snapshot_id"]);
- setCategory((U32)key["category"].asInteger());
- setContentType((U32)key["content_type"].asInteger());
- setClassifiedLocation(key["location_text"]);
- getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
- getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
- }
-}
-
-void LLPanelClassifiedEdit::onOpen(const LLSD& key)
-{
- mIsNew = key.isUndefined();
-
- scrollToTop();
-
- // classified is not created yet
- bool is_new = isNew() || isNewWithErrors();
-
- if(is_new)
- {
- resetData();
- resetControls();
-
- fillIn(key);
-
- if(isNew())
- {
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- }
- }
- else
- {
- LLPanelClassifiedInfo::onOpen(key);
- }
-
- std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
-
- enableVerbs(is_new);
- enableEditing(is_new);
- showEditing(!is_new);
- resetDirty();
- setInfoLoaded(false);
-}
-
-void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO == type)
- {
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if(c_info && getClassifiedId() == c_info->classified_id)
- {
- // see LLPanelClassifiedEdit::sendUpdate() for notes
- mIsNewWithErrors = false;
- // for just created classified - panel will probably be closed when we get here.
- if(!getVisible())
- {
- return;
- }
-
- enableEditing(true);
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setParcelId(c_info->parcel_id);
- setPosGlobal(c_info->pos_global);
-
- setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
- // *HACK see LLPanelClassifiedEdit::sendUpdate()
- setCategory(c_info->category - 1);
-
- bool mature = is_cf_mature(c_info->flags);
- bool auto_renew = is_cf_auto_renew(c_info->flags);
-
- setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
- getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
- getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
- getChildView("price_for_listing")->setEnabled(isNew());
-
- resetDirty();
- setInfoLoaded(true);
- enableVerbs(false);
-
- // for just created classified - in case user opened edit panel before processProperties() callback
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
- }
- }
-}
-
-BOOL LLPanelClassifiedEdit::isDirty() const
-{
- if(mIsNew)
- {
- return TRUE;
- }
-
- BOOL dirty = false;
-
- dirty |= LLPanelClassifiedInfo::isDirty();
- dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
- dirty |= getChild<LLUICtrl>("category")->isDirty();
- dirty |= getChild<LLUICtrl>("content_type")->isDirty();
- dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
- dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
-
- return dirty;
-}
-
-void LLPanelClassifiedEdit::resetDirty()
-{
- LLPanelClassifiedInfo::resetDirty();
- getChild<LLUICtrl>("classified_snapshot")->resetDirty();
- getChild<LLUICtrl>("classified_name")->resetDirty();
-
- LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
- // call blockUndo() to really reset dirty(and make isDirty work as intended)
- desc->blockUndo();
- desc->resetDirty();
-
- getChild<LLUICtrl>("category")->resetDirty();
- getChild<LLUICtrl>("content_type")->resetDirty();
- getChild<LLUICtrl>("auto_renew")->resetDirty();
- getChild<LLUICtrl>("price_for_listing")->resetDirty();
-}
-
-void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
-{
- mSaveButtonClickedSignal.connect(cb);
-}
-
-void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedEdit::resetControls()
-{
- LLPanelClassifiedInfo::resetControls();
-
- getChild<LLComboBox>("category")->setCurrentByIndex(0);
- getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
- getChild<LLUICtrl>("auto_renew")->setValue(false);
- getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
- getChildView("price_for_listing")->setEnabled(TRUE);
-}
-
-bool LLPanelClassifiedEdit::canClose()
-{
- return mCanClose;
-}
-
-void LLPanelClassifiedEdit::draw()
-{
- LLPanel::draw();
-
- // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
- // does not trigger callbacks when user navigates through images.
- stretchSnapshot();
-}
-
-void LLPanelClassifiedEdit::stretchSnapshot()
-{
- LLPanelClassifiedInfo::stretchSnapshot();
-
- getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
-}
-
-U32 LLPanelClassifiedEdit::getContentType()
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- return ct_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setContentType(U32 content_type)
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- ct_cb->setCurrentByIndex(content_type);
- ct_cb->resetDirty();
-}
-
-bool LLPanelClassifiedEdit::getAutoRenew()
-{
- return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-}
-
-void LLPanelClassifiedEdit::sendUpdate()
-{
- LLAvatarClassifiedInfo c_data;
-
- if(getClassifiedId().isNull())
- {
- setClassifiedId(LLUUID::generateNewID());
- }
-
- c_data.agent_id = gAgent.getID();
- c_data.classified_id = getClassifiedId();
- // *HACK
- // Categories on server start with 1 while combo-box index starts with 0
- c_data.category = getCategory() + 1;
- c_data.name = getClassifiedName();
- c_data.description = getDescription();
- c_data.parcel_id = getParcelId();
- c_data.snapshot_id = getSnapshotId();
- c_data.pos_global = getPosGlobal();
- c_data.flags = getFlags();
- c_data.price_for_listing = getPriceForListing();
-
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
-
- if(isNew())
- {
- // Lets assume there will be some error.
- // Successful sendClassifiedInfoUpdate will trigger processProperties and
- // let us know there was no error.
- mIsNewWithErrors = true;
- }
-}
-
-U32 LLPanelClassifiedEdit::getCategory()
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- return cat_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setCategory(U32 category)
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- cat_cb->setCurrentByIndex(category);
- cat_cb->resetDirty();
-}
-
-U8 LLPanelClassifiedEdit::getFlags()
-{
- bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-
- LLComboBox* content_cb = getChild<LLComboBox>("content_type");
- bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
-
- return pack_classified_flags_request(auto_renew, false, mature, false);
-}
-
-void LLPanelClassifiedEdit::enableVerbs(bool enable)
-{
- getChildView("save_changes_btn")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::enableEditing(bool enable)
-{
- getChildView("classified_snapshot")->setEnabled(enable);
- getChildView("classified_name")->setEnabled(enable);
- getChildView("classified_desc")->setEnabled(enable);
- getChildView("set_to_curr_location_btn")->setEnabled(enable);
- getChildView("category")->setEnabled(enable);
- getChildView("content_type")->setEnabled(enable);
- getChildView("price_for_listing")->setEnabled(enable);
- getChildView("auto_renew")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::showEditing(bool show)
-{
- getChildView("price_for_listing_label")->setVisible( show);
- getChildView("price_for_listing")->setVisible( show);
-}
-
-std::string LLPanelClassifiedEdit::makeClassifiedName()
-{
- std::string name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- name = parcel->getName();
- }
-
- if(!name.empty())
- {
- return name;
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- name = region->getName();
- }
-
- return name;
-}
-
-S32 LLPanelClassifiedEdit::getPriceForListing()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPanelClassifiedEdit::setPriceForListing(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-void LLPanelClassifiedEdit::onSetLocationClick()
-{
- setPosGlobal(gAgent.getPositionGlobal());
- setParcelId(LLUUID::null);
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
-
- // mark classified as dirty
- setValue(LLSD());
-
- onChange();
-}
-
-void LLPanelClassifiedEdit::onChange()
-{
- enableVerbs(isDirty());
-}
-
-void LLPanelClassifiedEdit::onSaveClick()
-{
- mCanClose = false;
-
- if(!isValidName())
- {
- notifyInvalidName();
- return;
- }
- if(isNew() || isNewWithErrors())
- {
- if(gStatusBar->getBalance() < getPriceForListing())
- {
- LLNotificationsUtil::add("ClassifiedInsufficientFunds");
- return;
- }
-
- mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- if(!mPublishFloater)
- {
- mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- mPublishFloater->setPublishClickedCallback(boost::bind
- (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
- }
-
- // set spinner value before it has focus or value wont be set
- mPublishFloater->setPrice(getPriceForListing());
- mPublishFloater->openFloater(mPublishFloater->getKey());
- mPublishFloater->center();
- }
- else
- {
- doSave();
- }
-}
-
-void LLPanelClassifiedEdit::doSave()
-{
- mCanClose = true;
- sendUpdate();
- resetDirty();
-
- mSaveButtonClickedSignal(this, LLSD());
-}
-
-void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
-{
- setPriceForListing(mPublishFloater->getPrice());
-
- doSave();
-}
-
-std::string LLPanelClassifiedEdit::getLocationNotice()
-{
- static std::string location_notice = getString("location_notice");
- return location_notice;
-}
-
-bool LLPanelClassifiedEdit::isValidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- return false;
- }
- if (!isalnum(name[0]))
- {
- return false;
- }
-
- return true;
-}
-
-void LLPanelClassifiedEdit::notifyInvalidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- LLNotificationsUtil::add("BlankClassifiedName");
- }
- else if (!isalnum(name[0]))
- {
- LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
- }
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- ctrl->setVisible(TRUE);
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- ctrl->setVisible(FALSE);
-}
-
-void LLPanelClassifiedEdit::onTextureSelected()
-{
- setSnapshotId(mSnapshotCtrl->getValue().asUUID());
- onChange();
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
- LLFloater::postBuild();
-
- childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
- childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
- return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index b292782615..471becd0f7 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.h
- * @brief LLPanelClassified class definition
+ * @brief LLPanelClassifiedInfo class definition
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -35,39 +35,16 @@
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
-#include "lluuid.h"
-#include "v3dmath.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
-class LLUICtrl;
-
-class LLPublishClassifiedFloater : public LLFloater
-{
-public:
- LLPublishClassifiedFloater(const LLSD& key);
- virtual ~LLPublishClassifiedFloater();
-
- /*virtual*/ BOOL postBuild();
-
- void setPrice(S32 price);
- S32 getPrice();
-
- void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
- void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-
-private:
-};
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(LLPanelClassifiedInfo);
public:
- static LLPanelClassifiedInfo* create();
-
+ LLPanelClassifiedInfo();
virtual ~LLPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
@@ -135,18 +112,12 @@ public:
const LLVector3d& global_pos,
const std::string& sim_name);
- void setExitCallback(const commit_callback_t& cb);
-
- void setEditClassifiedCallback(const commit_callback_t& cb);
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
protected:
- LLPanelClassifiedInfo();
-
virtual void resetData();
virtual void resetControls();
@@ -165,7 +136,6 @@ protected:
void onMapClick();
void onTeleportClick();
- void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
@@ -202,100 +172,4 @@ private:
static panel_list_t sAllPanels;
};
-class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
-{
- LOG_CLASS(LLPanelClassifiedEdit);
-public:
-
- static LLPanelClassifiedEdit* create();
-
- virtual ~LLPanelClassifiedEdit();
-
- /*virtual*/ BOOL postBuild();
-
- void fillIn(const LLSD& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void resetDirty();
-
- void setSaveCallback(const commit_signal_t::slot_type& cb);
-
- void setCancelCallback(const commit_signal_t::slot_type& cb);
-
- /*virtual*/ void resetControls();
-
- bool isNew() { return mIsNew; }
-
- bool isNewWithErrors() { return mIsNewWithErrors; }
-
- bool canClose();
-
- void draw();
-
- void stretchSnapshot();
-
- U32 getCategory();
-
- void setCategory(U32 category);
-
- U32 getContentType();
-
- void setContentType(U32 content_type);
-
- bool getAutoRenew();
-
- S32 getPriceForListing();
-
-protected:
-
- LLPanelClassifiedEdit();
-
- void sendUpdate();
-
- void enableVerbs(bool enable);
-
- void enableEditing(bool enable);
-
- void showEditing(bool show);
-
- std::string makeClassifiedName();
-
- void setPriceForListing(S32 price);
-
- U8 getFlags();
-
- std::string getLocationNotice();
-
- bool isValidName();
-
- void notifyInvalidName();
-
- void onSetLocationClick();
- void onChange();
- void onSaveClick();
-
- void doSave();
-
- void onPublishFloaterPublishClicked();
-
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
- void onTextureSelected();
-
-private:
- bool mIsNew;
- bool mIsNewWithErrors;
- bool mCanClose;
-
- LLPublishClassifiedFloater* mPublishFloater;
-
- commit_signal_t mSaveButtonClickedSignal;
-};
-
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
index a169712bd8..d17845ebc5 100644
--- a/indra/newview/llpaneleditsky.cpp
+++ b/indra/newview/llpaneleditsky.cpp
@@ -108,6 +108,8 @@ namespace
const std::string FIELD_SKY_DENSITY_DROPLET_RADIUS("droplet_radius");
const std::string FIELD_SKY_DENSITY_ICE_LEVEL("ice_level");
+ const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
+
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f);
const F32 SLIDER_SCALE_GLOW_R(20.0f);
@@ -150,6 +152,7 @@ BOOL LLPanelSettingsSkyAtmosTab::postBuild()
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoistureLevelChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDropletRadiusChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onIceLevelChanged(); });
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
refresh();
return TRUE;
@@ -172,6 +175,7 @@ void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setEnabled(enabled);
}
}
@@ -203,10 +207,12 @@ void LLPanelSettingsSkyAtmosTab::refresh()
F32 moisture_level = mSkySettings->getSkyMoistureLevel();
F32 droplet_radius = mSkySettings->getSkyDropletRadius();
F32 ice_level = mSkySettings->getSkyIceLevel();
+ F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance();
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance);
}
//-------------------------------------------------------------------------
@@ -311,6 +317,15 @@ void LLPanelSettingsSkyAtmosTab::onIceLevelChanged()
setIsDirty();
}
+void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged()
+{
+ if (!mSkySettings) return;
+ F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
+ mSkySettings->setReflectionProbeAmbiance(ambiance);
+ mSkySettings->update();
+ setIsDirty();
+}
+
//==========================================================================
LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() :
LLPanelSettingsSky()
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index cb63d40b0c..cd89e02eea 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -79,6 +79,7 @@ private:
void onMoistureLevelChanged();
void onDropletRadiusChanged();
void onIceLevelChanged();
+ void onReflectionProbeAmbianceChanged();
};
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index be11a4a9f3..ea10aa75ae 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1308,7 +1308,9 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
- gMorphView->updateCamera();
+ // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
+ gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
+ gMorphView->updateCamera();
}
}
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 9d5afd1a6a..11111f2a2e 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
-#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 71657239a6..c6e0bc5153 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
+#include "llagent.h"
#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -45,10 +46,20 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "llface.h"
+#include "llgltfmateriallist.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h" // gInventory
+#include "llinventorymodelbackgroundfetch.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmaterialeditor.h"
+#include "llmediactrl.h"
#include "llmediaentry.h"
+#include "llmenubutton.h"
#include "llnotificationsutil.h"
+#include "llpanelcontents.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -57,6 +68,8 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "lltooldraganddrop.h"
+#include "lltoolface.h"
+#include "lltoolmgr.h"
#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
@@ -69,18 +82,35 @@
#include "llpluginclassmedia.h"
#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+
+
+#include "llagent.h"
+#include "llfilesystem.h"
+#include "llviewerassetupload.h"
+#include "llviewermenufile.h"
+#include "llsd.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llinventorymodel.h"
+
+using namespace std::literals;
+
//
// Constant definitions for comboboxes
// Must match the commbobox definitions in panel_tools_texture.xml
//
const S32 MATMEDIA_MATERIAL = 0; // Material
-const S32 MATMEDIA_MEDIA = 1; // Media
+const S32 MATMEDIA_PBR = 1; // PBR
+const S32 MATMEDIA_MEDIA = 2; // Media
const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
const S32 MATTYPE_NORMAL = 1; // Normal map
const S32 MATTYPE_SPECULAR = 2; // Specular map
const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
const S32 BUMPY_TEXTURE = 18; // use supplied normal map
const S32 SHINY_TEXTURE = 4; // use supplied specular map
+const S32 PBRTYPE_BASE_COLOR = 0; // PBR Base Color
+const S32 PBRTYPE_NORMAL = 1; // PBR Normal
+const S32 PBRTYPE_METALLIC = 2; // PBR Metallic
BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP);
@@ -92,11 +122,23 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
- (radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+
+ LLRender::eTexIndex channel_to_edit = LLRender::DIFFUSE_MAP;
+ if (mComboMatMedia)
+ {
+ U32 matmedia_selection = mComboMatMedia->getCurrentIndex();
+ if (matmedia_selection == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ if (matmedia_selection == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_pbr_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ }
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
@@ -154,6 +196,8 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+ childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
+ childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@@ -165,7 +209,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -176,6 +219,29 @@ BOOL LLPanelFace::postBuild()
setMouseOpaque(FALSE);
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setDefaultImageAssetID(LLUUID::null);
+ pbr_ctrl->setBlankImageAssetID(LLUUID::null); // should there be some empty default material?
+ pbr_ctrl->setCommitCallback(boost::bind(&LLPanelFace::onCommitPbr, this, _2));
+ pbr_ctrl->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelPbr, this, _2));
+ pbr_ctrl->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectPbr, this, _2));
+ pbr_ctrl->setDragCallback(boost::bind(&LLPanelFace::onDragPbr, this, _2));
+ pbr_ctrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onPbrSelectionChanged, this, _1));
+ pbr_ctrl->setOnCloseCallback(boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2));
+
+ pbr_ctrl->setFollowsTop();
+ pbr_ctrl->setFollowsLeft();
+ pbr_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ pbr_ctrl->setBakeTextureEnabled(false);
+ pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL);
+
+ // TODO - design real UI for activating live editing
+ pbr_ctrl->setRightMouseUpCallback(boost::bind(&LLPanelFace::onPbrStartEditing, this));
+ }
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -279,26 +345,38 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
- mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
+ mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
if(mComboMatMedia)
{
- mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
- mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
{
radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type)
+ {
+ radio_pbr_type->setCommitCallback(LLPanelFace::onCommitPbrType, this);
+ radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR);
+ }
+
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
-
+
+ mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn");
+ mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn");
+
+ mTitleMedia = getChild<LLMediaCtrl>("title_media");
+ mTitleMediaText = getChild<LLTextBox>("media_info");
clearCtrls();
@@ -307,17 +385,33 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
- mIsAlpha(false)
+ mIsAlpha(false),
+ mComboMatMedia(NULL),
+ mTitleMedia(NULL),
+ mTitleMediaText(NULL),
+ mNeedMediaTitle(true)
{
- USE_TEXTURE = LLTrans::getString("use_texture");
+ USE_TEXTURE = LLTrans::getString("use_texture");
+ mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2));
}
-
LLPanelFace::~LLPanelFace()
{
- // Children all cleaned up by default view destructor.
+ unloadMedia();
}
+void LLPanelFace::draw()
+{
+ updateCopyTexButton();
+
+ // grab media name/title and update the UI widget
+ // Todo: move it, it's preferable not to update
+ // labels inside draw
+ updateMediaTitle();
+
+ LLPanel::draw();
+}
void LLPanelFace::sendTexture()
{
@@ -442,20 +536,42 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
{
BOOL valid;
F32 value;
-
- LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
std::string prefix;
- switch (radio_mat_type->getSelectedIndex())
+ U32 materials_media = mPanel->getChild<LLComboBox>("combobox matmedia")->getCurrentIndex();
+
+ if (MATMEDIA_PBR == materials_media)
{
- case MATTYPE_DIFFUSE:
- prefix = "Tex";
- break;
- case MATTYPE_NORMAL:
- prefix = "bumpy";
- break;
- case MATTYPE_SPECULAR:
- prefix = "shiny";
- break;
+ LLRadioGroup * radio_pbr_type = mPanel->getChild<LLRadioGroup>("radio_pbr_type");
+ switch (radio_pbr_type->getSelectedIndex())
+ {
+ case PBRTYPE_BASE_COLOR:
+ prefix = "Tex";
+ break;
+ case PBRTYPE_NORMAL:
+ prefix = "bumpy";
+ break;
+ case PBRTYPE_METALLIC:
+ prefix = "shiny";
+ break;
+ }
+ }
+ else
+ {
+ // Effectively the same as MATMEDIA_PBR sans using different radio,
+ // separate for the sake of clarity
+ LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
+ switch (radio_mat_type->getSelectedIndex())
+ {
+ case MATTYPE_DIFFUSE:
+ prefix = "Tex";
+ break;
+ case MATTYPE_NORMAL:
+ prefix = "bumpy";
+ break;
+ case MATTYPE_SPECULAR:
+ prefix = "shiny";
+ break;
+ }
}
LLSpinCtrl * ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleU");
@@ -806,45 +922,52 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("button align")->setEnabled(editable);
+ childSetEnabled("button align", editable);
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- if (combobox_matmedia)
- {
- if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
- {
- combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
- }
- }
- else
- {
- LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
- }
- getChildView("combobox matmedia")->setEnabled(editable);
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+ mComboMatMedia->setEnabled(editable);
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- if(radio_mat_type)
- {
- if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
- {
- radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
- }
+ if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
+ {
+ radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
+ }
+ radio_mat_type->setEnabled(editable);
- }
- else
- {
- LL_WARNS("Materials") << "failed getChild for 'radio_material_type'" << LL_ENDL;
- }
+ LLRadioGroup* radio_pbr_type = getChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type->getSelectedIndex() < PBRTYPE_BASE_COLOR)
+ {
+ radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR);
+ }
+ radio_pbr_type->setEnabled(editable);
- getChildView("radio_material_type")->setEnabled(editable);
getChildView("checkbox_sync_settings")->setEnabled(editable);
childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
updateVisibility();
bool identical = true; // true because it is anded below
- bool identical_diffuse = false;
- bool identical_norm = false;
- bool identical_spec = false;
+ bool identical_diffuse = false;
+ bool identical_norm = false;
+ bool identical_spec = false;
+
+ // pbr material
+ bool has_pbr_material = false;
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID pbr_id;
+ bool identical_pbr;
+ LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr);
+ identical &= identical_pbr;
+
+ pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
+ pbr_ctrl->setEnabled(editable);
+ pbr_ctrl->setImageAssetID(pbr_id);
+ has_pbr_material = pbr_id.notNull();
+ }
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
@@ -856,32 +979,32 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
// Color swatch
{
- getChildView("color label")->setEnabled(editable);
+ getChildView("color label")->setEnabled(editable && !has_pbr_material);
}
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
LLColor4 color = LLColor4::white;
bool identical_color = false;
- if(mColorSwatch)
+ if(color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = mColorSwatch->get();
+ LLColor4 prev_color = color_swatch->get();
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable);
+ color_swatch->setOriginal(color);
+ color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable);
+ color_swatch->setEnabled( editable );
+ color_swatch->setCanApplyImmediately( editable );
}
// Color transparency
- getChildView("color trans")->setEnabled(editable);
+ getChildView("color trans")->setEnabled(editable && !has_pbr_material);
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable);
+ getChildView("ColorTrans")->setEnabled(editable && !has_pbr_material);
// Specular map
LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
@@ -926,7 +1049,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
U8 bumpy = 0;
// Bumpy
- {
+ {
bool identical_bumpy = false;
LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
@@ -947,7 +1070,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChildView("combobox bumpiness")->setEnabled(editable);
getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
getChildView("label bumpiness")->setEnabled(editable);
- }
+ }
// Texture
{
@@ -1022,10 +1145,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setTentative(FALSE);
texture_ctrl->setEnabled(editable);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
@@ -1048,10 +1171,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setTentative(TRUE);
texture_ctrl->setEnabled(editable);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
@@ -1140,9 +1263,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
- getChildView("TexScaleU")->setEnabled(editable);
- getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexScaleU")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyScaleU")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyScaleU")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexScaleU")->setEnabled(editable);
+ getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+ }
BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
@@ -1179,9 +1311,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL norm_scale_tentative = !identical_norm_scale_t;
BOOL spec_scale_tentative = !identical_spec_scale_t;
- getChildView("TexScaleV")->setEnabled(editable);
- getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexScaleV")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyScaleV")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyScaleV")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexScaleV")->setEnabled(editable);
+ getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+ }
if (force_set_values)
{
@@ -1225,9 +1366,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
- getChildView("TexOffsetU")->setEnabled(editable);
- getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexOffsetU")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyOffsetU")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyOffsetU")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexOffsetU")->setEnabled(editable);
+ getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
+ }
}
{
@@ -1255,9 +1405,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
- getChildView("TexOffsetV")->setEnabled(editable);
- getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexOffsetV")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyOffsetV")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyOffsetV")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexOffsetV")->setEnabled(editable);
+ getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
+ }
}
// Texture rotation
@@ -1281,10 +1440,19 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
-
- getChildView("TexRot")->setEnabled(editable);
- getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
+
+ if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR)
+ {
+ getChildView("TexRot")->setEnabled(editable && has_pbr_material);
+ getChildView("shinyRot")->setEnabled(editable && has_pbr_material);
+ getChildView("bumpyRot")->setEnabled(editable && has_pbr_material);
+ }
+ else
+ {
+ getChildView("TexRot")->setEnabled(editable);
+ getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
+ }
getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
@@ -1301,8 +1469,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLSelectedTE::getGlow(glow,identical_glow);
getChild<LLUICtrl>("glow")->setValue(glow);
getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
- getChildView("glow")->setEnabled(editable);
- getChildView("glow label")->setEnabled(editable);
+ getChildView("glow")->setEnabled(editable && !has_pbr_material);
+ getChildView("glow label")->setEnabled(editable && !has_pbr_material);
}
{
@@ -1350,42 +1518,61 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
if (mComboTexGen)
- {
+ {
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
- BOOL enabled = editable && (index != 1);
- BOOL identical_repeats = true;
+ bool enabled = editable && (index != 1);
+ bool identical_repeats = true;
+ S32 material_selection = mComboMatMedia->getCurrentIndex();
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
+ U32 material_type = MATTYPE_DIFFUSE;
+ if (material_selection == MATMEDIA_MATERIAL)
+ {
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ else if (material_selection == MATMEDIA_PBR)
+ {
+ enabled = editable && has_pbr_material;
+ material_type = radio_pbr_type->getSelectedIndex();
+ }
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
- switch (material_type)
- {
- default:
- case MATTYPE_DIFFUSE:
- {
- enabled = editable && !id.isNull();
- identical_repeats = identical_diff_repeats;
- repeats = repeats_diff;
- }
- break;
+ switch (material_type)
+ {
+ default:
+ case MATTYPE_DIFFUSE:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = editable && !id.isNull();
+ }
+ identical_repeats = identical_diff_repeats;
+ repeats = repeats_diff;
+ }
+ break;
- case MATTYPE_SPECULAR:
- {
- enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
- identical_repeats = identical_spec_repeats;
- repeats = repeats_spec;
- }
- break;
+ case MATTYPE_SPECULAR:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
+ }
+ identical_repeats = identical_spec_repeats;
+ repeats = repeats_spec;
+ }
+ break;
- case MATTYPE_NORMAL:
- {
- enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
- identical_repeats = identical_norm_repeats;
- repeats = repeats_norm;
- }
- break;
- }
+ case MATTYPE_NORMAL:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
+ }
+ identical_repeats = identical_norm_repeats;
+ repeats = repeats_norm;
+ }
+ break;
+ }
BOOL repeats_tentative = !identical_repeats;
@@ -1409,7 +1596,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLMaterialPtr material;
LLSelectedTEMaterial::getCurrent(material, identical);
- if (material && editable)
+ if (material && editable)
{
LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL;
@@ -1508,6 +1695,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
}
}
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (selected_count == 1);
+ mMenuClipboardColor->setEnabled(editable && single_volume);
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
@@ -1525,6 +1715,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
clearCtrls();
// Disable non-UICtrls
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setImageAssetID(LLUUID::null);
+ pbr_ctrl->setEnabled(FALSE);
+ }
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
if(texture_ctrl)
{
@@ -1568,12 +1764,772 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
+void LLPanelFace::updateCopyTexButton()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
+ && !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
+ && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1));
+ std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
+ mMenuClipboardTexture->setToolTip(tooltip);
+
+}
+
void LLPanelFace::refresh()
{
LL_DEBUGS("Materials") << LL_ENDL;
getState();
}
+void LLPanelFace::refreshMedia()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+
+ if (!(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ && first_object->permModify()
+ ))
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ mTitleMediaText->clear();
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if (!has_media_capability)
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for (; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterToolsMedia")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor<bool>
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ LLMediaEntry get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("add_media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ {
+ // TODO: get media title and set it.
+ mTitleMediaText->clear();
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ }
+
+ getChildView("delete_media")->setEnabled(bool_has_media && editable);
+ // TODO: display a list of all media on the face - use 'identical' flag
+ }
+ else // not all face has media but at least one does.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+
+ if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ }
+ else
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ }
+
+ getChildView("delete_media")->setEnabled(TRUE);
+ }
+
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ if (materials_media == MATMEDIA_MEDIA)
+ {
+ // currently displaying media info, navigateTo and update title
+ navigateToTitleMedia(media_title);
+ }
+ else
+ {
+ // Media can be heavy, don't keep it around
+ // MAC specific: MAC doesn't support setVolume(0) so if not
+ // unloaded, it might keep playing audio until user closes editor
+ unloadMedia();
+ mNeedMediaTitle = false;
+ }
+
+ mTitleMediaText->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+}
+
+void LLPanelFace::unloadMedia()
+{
+ // destroy media source used to grab media title
+ if (mTitleMedia)
+ mTitleMedia->unloadMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelFace::navigateToTitleMedia( const std::string url )
+{
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
+
+ LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
+ if (impl)
+ {
+ // if it's a page with a movie, we don't want to hear it
+ impl->setVolume(0);
+ };
+ }
+
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
+}
+
+bool LLPanelFace::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
+ &owner_mask_on, &owner_mask_off);
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
+ &group_mask_on, &group_mask_off);
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off);
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if (valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms)
+ {
+
+ if ((owner_mask_on & PERM_MODIFY) ||
+ (group_mask_on & PERM_MODIFY) ||
+ (everyone_mask_on & PERM_MODIFY))
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+
+void LLPanelFace::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+void LLPanelFace::updateMediaSettings()
+{
+ bool identical(false);
+ std::string base_key("");
+ std::string value_str("");
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_controls, value_u8);
+ base_key = std::string(LLMediaEntry::CONTROLS_KEY);
+ mMediaSettings[base_key] = value_u8;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool);
+ base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_home_url, value_str);
+ base_key = std::string(LLMediaEntry::HOME_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_current_url, value_str);
+ base_key = std::string(LLMediaEntry::CURRENT_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int);
+ base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int);
+ base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool);
+ base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool);
+ base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist URLs
+ std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::vector<std::string> get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str);
+ base_key = std::string(LLMediaEntry::WHITELIST_KEY);
+ mMediaSettings[base_key].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while (iter != value_vector_str.end())
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[base_key].append(white_list_url);
+ ++iter;
+ };
+
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+}
+
+void LLPanelFace::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if (!mNeedMediaTitle)
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI())
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if (!media_title.empty())
+ {
+ // update the UI widget
+ if (mTitleMediaText)
+ {
+ mTitleMediaText->setText(media_title);
+
+ // stop looking for a title when we get one
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
//
// Static functions
//
@@ -1632,49 +2588,58 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->updateShinyControls(false,true);
self->updateBumpyControls(false,true);
self->updateUI();
+ self->refreshMedia();
}
-// static
void LLPanelFace::updateVisibility()
-{
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
- LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+{
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ LLComboBox* combo_shininess = findChild<LLComboBox>("combobox shininess");
+ LLComboBox* combo_bumpiness = findChild<LLComboBox>("combobox bumpiness");
+ if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
- getChildView("radio_material_type")->setVisible(!show_media);
+ U32 pbr_type = radio_pbr_type->getSelectedIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_material = materials_media == MATMEDIA_MATERIAL;
+ bool show_pbr = materials_media == MATMEDIA_PBR;
+ bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ bool show_pbr_base_color = show_pbr && (pbr_type == PBRTYPE_BASE_COLOR) && mComboMatMedia->getEnabled();
+ bool show_pbr_normal = show_pbr && (pbr_type == PBRTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_pbr_metallic = show_pbr && (pbr_type == PBRTYPE_METALLIC) && mComboMatMedia->getEnabled();
+
+ radio_mat_type->setVisible(show_material);
+ radio_pbr_type->setVisible(show_pbr);
// Media controls
- getChildView("media_info")->setVisible(show_media);
+ mTitleMediaText->setVisible(show_media);
getChildView("add_media")->setVisible(show_media);
getChildView("delete_media")->setVisible(show_media);
getChildView("button align")->setVisible(show_media);
// Diffuse texture controls
- getChildView("texture control")->setVisible(show_texture && !show_media);
- getChildView("label alphamode")->setVisible(show_texture && !show_media);
- getChildView("combobox alphamode")->setVisible(show_texture && !show_media);
+ getChildView("texture control")->setVisible(show_texture && show_material);
+ getChildView("label alphamode")->setVisible(show_texture && show_material);
+ getChildView("combobox alphamode")->setVisible(show_texture && show_material);
getChildView("label maskcutoff")->setVisible(false);
getChildView("maskcutoff")->setVisible(false);
- if (show_texture && !show_media)
+ if ((show_texture && show_material) || show_pbr)
{
updateAlphaControls();
}
- getChildView("TexScaleU")->setVisible(show_texture);
- getChildView("TexScaleV")->setVisible(show_texture);
- getChildView("TexRot")->setVisible(show_texture);
- getChildView("TexOffsetU")->setVisible(show_texture);
- getChildView("TexOffsetV")->setVisible(show_texture);
+ // texture scale and position controls are shared between bpr and non-pbr textures
+ getChildView("TexScaleU")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexScaleV")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexRot")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexOffsetU")->setVisible(show_texture || show_pbr_base_color);
+ getChildView("TexOffsetV")->setVisible(show_texture || show_pbr_base_color);
// Specular map controls
getChildView("shinytexture control")->setVisible(show_shininess);
@@ -1690,11 +2655,11 @@ void LLPanelFace::updateVisibility()
{
updateShinyControls();
}
- getChildView("shinyScaleU")->setVisible(show_shininess);
- getChildView("shinyScaleV")->setVisible(show_shininess);
- getChildView("shinyRot")->setVisible(show_shininess);
- getChildView("shinyOffsetU")->setVisible(show_shininess);
- getChildView("shinyOffsetV")->setVisible(show_shininess);
+ getChildView("shinyScaleU")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyScaleV")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyRot")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyOffsetU")->setVisible(show_shininess || show_pbr_normal);
+ getChildView("shinyOffsetV")->setVisible(show_shininess || show_pbr_normal);
// Normal map controls
if (show_bumpiness)
@@ -1704,13 +2669,14 @@ void LLPanelFace::updateVisibility()
getChildView("bumpytexture control")->setVisible(show_bumpiness);
getChildView("combobox bumpiness")->setVisible(show_bumpiness);
getChildView("label bumpiness")->setVisible(show_bumpiness);
- getChildView("bumpyScaleU")->setVisible(show_bumpiness);
- getChildView("bumpyScaleV")->setVisible(show_bumpiness);
- getChildView("bumpyRot")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
- getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
-
-
+ getChildView("bumpyScaleU")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyScaleV")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyRot")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyOffsetU")->setVisible(show_bumpiness || show_pbr_metallic);
+ getChildView("bumpyOffsetV")->setVisible(show_bumpiness || show_pbr_metallic);
+
+ // PBR controls
+ getChildView("pbr_control")->setVisible(show_pbr);
}
// static
@@ -1726,6 +2692,16 @@ void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
}
// static
+void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateUI();
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
@@ -1787,12 +2763,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_material = (materials_media == MATMEDIA_MATERIAL);
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -1866,11 +2841,10 @@ void LLPanelFace::updateAlphaControls()
U32 alpha_value = comboAlphaMode->getCurrentIndex();
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
U32 mat_media = MATMEDIA_MATERIAL;
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- mat_media = combobox_matmedia->getCurrentIndex();
+ mat_media = mComboMatMedia->getCurrentIndex();
}
U32 mat_type = MATTYPE_DIFFUSE;
@@ -1910,21 +2884,81 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
+BOOL LLPanelFace::onDragPbr(LLUICtrl*, LLInventoryItem* item)
+{
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
+}
+
+void LLPanelFace::onCommitPbr(const LLSD& data)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
+ }
+}
+
+void LLPanelFace::onCancelPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->selectionRevertGLTFMaterials();
+}
+
+void LLPanelFace::onSelectPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->saveSelectedObjectTextures();
+
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
+ LLSelectedTEMaterial::setMaterialID(this, id);
+ }
+}
+
+// static
BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
{
- BOOL accept = TRUE;
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
- {
- accept = FALSE;
- break;
- }
- }
- return accept;
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
}
void LLPanelFace::onCommitTexture( const LLSD& data )
@@ -2027,6 +3061,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata)
+{
+ // check if multiple faces are selected
+ if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia(ctrl, userdata);
+ }
+}
+
+// static
+bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD());
+ if (LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+// static
+bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLFloaterReg::showInstance("media_settings");
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
@@ -2404,12 +3509,20 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
- LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
- LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
+ U32 material_type = 0;
+ if (materials_media == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_pbr_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ if (materials_media == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
- U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
F32 obj_scale_s = 1.0f;
@@ -2538,15 +3651,842 @@ void LLPanelFace::onAlignTexture(void* userdata)
self->alignTestureLayer();
}
+enum EPasteMode
+{
+ PASTE_COLOR,
+ PASTE_TEXTURE
+};
+
+struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor
+{
+ LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) :
+ mPanelFace(panel), mMode(mode) {}
+
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ switch (mMode)
+ {
+ case PASTE_COLOR:
+ mPanelFace->onPasteColor(objectp, te);
+ break;
+ case PASTE_TEXTURE:
+ mPanelFace->onPasteTexture(objectp, te);
+ break;
+ }
+ return true;
+ }
+private:
+ LLPanelFace *mPanelFace;
+ EPasteMode mMode;
+};
+
+struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
+{
+ LLPanelFaceUpdateFunctor(bool update_media, bool update_pbr)
+ : mUpdateMedia(update_media)
+ , mUpdatePbr(update_pbr)
+ {}
+
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (mUpdatePbr)
+ {
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+ }
+
+ object->sendTEUpdate();
+
+ if (mUpdateMedia)
+ {
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ if (vo && vo->hasMedia())
+ {
+ vo->sendMediaDataUpdate();
+ }
+ }
+ return true;
+ }
+private:
+ bool mUpdateMedia;
+ bool mUpdatePbr;
+};
+
+struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
+{
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && objectp->getTE(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ const LLMediaEntry *media_data = tep->getMediaData();
+ if (media_data)
+ {
+ if (media_data->getCurrentURL().empty() && media_data->getAutoPlay())
+ {
+ viewer_media_t media_impl =
+ LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID());
+ if (media_impl)
+ {
+ media_impl->navigateHome();
+ }
+ }
+ }
+ }
+ return true;
+ }
+};
+
+void LLPanelFace::onCopyColor()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("color"))
+ {
+ mClipboardParams["color"].clear();
+ }
+ else
+ {
+ mClipboardParams["color"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["color_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD(); // Note: includes a lot more than just color/alpha/glow
+
+ mClipboardParams["color"].append(te_data);
+ }
+ }
+ }
+}
-// TODO: I don't know who put these in or what these are for???
-void LLPanelFace::setMediaURL(const std::string& url)
+void LLPanelFace::onPasteColor()
{
+ if (!mClipboardParams.has("color"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste color due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(false, false);
+ selected_objects->applyToObjects(&sendfunc);
}
-void LLPanelFace::setMediaType(const std::string& mime_type)
+
+void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te)
{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Color / Alpha
+ if (te_data["te"].has("colors"))
+ {
+ LLColor4 color = tep->getColor();
+
+ LLColor4 clip_color;
+ clip_color.setValue(te_data["te"]["colors"]);
+
+ // Color
+ color.mV[VRED] = clip_color.mV[VRED];
+ color.mV[VGREEN] = clip_color.mV[VGREEN];
+ color.mV[VBLUE] = clip_color.mV[VBLUE];
+
+ // Alpha
+ color.mV[VALPHA] = clip_color.mV[VALPHA];
+
+ objectp->setTEColor(te, color);
+ }
+
+ // Color/fullbright
+ if (te_data["te"].has("fullbright"))
+ {
+ objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger());
+ }
+
+ // Glow
+ if (te_data["te"].has("glow"))
+ {
+ objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal());
+ }
+ }
+ }
}
+void LLPanelFace::onCopyTexture()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("texture"))
+ {
+ mClipboardParams["texture"].clear();
+ }
+ else
+ {
+ mClipboardParams["texture"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["texture_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD();
+ te_data["te"]["shiny"] = tep->getShiny();
+ te_data["te"]["bumpmap"] = tep->getBumpmap();
+ te_data["te"]["bumpshiny"] = tep->getBumpShiny();
+ te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+ te_data["te"]["pbr"] = objectp->getRenderMaterialID(te);
+
+ if (te_data["te"].has("imageid"))
+ {
+ LLUUID item_id;
+ LLUUID id = te_data["te"]["imageid"].asUUID();
+ bool from_library = get_is_predefined_texture(id);
+ bool full_perm = from_library;
+
+ if (!full_perm
+ && objectp->permCopy()
+ && objectp->permTransfer()
+ && objectp->permModify())
+ {
+ // If agent created this object and nothing is limiting permissions, mark as full perm
+ // If agent was granted permission to edit objects owned and created by somebody else, mark full perm
+ // This check is not perfect since we can't figure out whom textures belong to so this ended up restrictive
+ std::string creator_app_link;
+ LLUUID creator_id;
+ LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link);
+ full_perm = objectp->mOwnerID == creator_id;
+ }
+
+ if (id.notNull() && !full_perm)
+ {
+ std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id);
+ if (iter != asset_item_map.end())
+ {
+ item_id = iter->second;
+ }
+ else
+ {
+ // What this does is simply searches inventory for item with same asset id,
+ // as result it is Hightly unreliable, leaves little control to user, borderline hack
+ // but there are little options to preserve permissions - multiple inventory
+ // items might reference same asset and inventory search is expensive.
+ bool no_transfer = false;
+ if (objectp->getInventoryItemByAsset(id))
+ {
+ no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm();
+ }
+ item_id = get_copy_free_item_by_asset_id(id, no_transfer);
+ // record value to avoid repeating inventory search when possible
+ asset_item_map[id] = item_id;
+ }
+ }
+
+ if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID()))
+ {
+ full_perm = true;
+ from_library = true;
+ }
+
+ {
+ te_data["te"]["itemfullperm"] = full_perm;
+ te_data["te"]["fromlibrary"] = from_library;
+
+ // If full permission object, texture is free to copy,
+ // but otherwise we need to check inventory and extract permissions
+ //
+ // Normally we care only about restrictions for current user and objects
+ // don't inherit any 'next owner' permissions from texture, so there is
+ // no need to record item id if full_perm==true
+ if (!full_perm && !from_library && item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ te_data["te"]["imageitemid"] = item_id;
+ te_data["te"]["itemfullperm"] = itemp->getIsFullPerm();
+ if (!itemp->isFinished())
+ {
+ // needed for dropTextureAllFaces
+ LLInventoryModelBackgroundFetch::instance().start(item_id, false);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ LLMaterialPtr material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ LLSD mat_data;
+
+ mat_data["NormMap"] = material_ptr->getNormalID();
+ mat_data["SpecMap"] = material_ptr->getSpecularID();
+
+ mat_data["NormRepX"] = material_ptr->getNormalRepeatX();
+ mat_data["NormRepY"] = material_ptr->getNormalRepeatY();
+ mat_data["NormOffX"] = material_ptr->getNormalOffsetX();
+ mat_data["NormOffY"] = material_ptr->getNormalOffsetY();
+ mat_data["NormRot"] = material_ptr->getNormalRotation();
+
+ mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX();
+ mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY();
+ mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX();
+ mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY();
+ mat_data["SpecRot"] = material_ptr->getSpecularRotation();
+
+ mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue();
+ mat_data["SpecExp"] = material_ptr->getSpecularLightExponent();
+ mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity();
+ mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff();
+ mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode();
+
+ // Replace no-copy textures, destination texture will get used instead if available
+ if (mat_data.has("NormMap"))
+ {
+ LLUUID id = mat_data["NormMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["NormMapNoCopy"] = true;
+ }
+
+ }
+ if (mat_data.has("SpecMap"))
+ {
+ LLUUID id = mat_data["SpecMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["SpecMapNoCopy"] = true;
+ }
+
+ }
+
+ te_data["material"] = mat_data;
+ }
+
+ mClipboardParams["texture"].append(te_data);
+ }
+ }
+ }
+}
+
+void LLPanelFace::onPasteTexture()
+{
+ if (!mClipboardParams.has("texture"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ bool full_perm_object = true;
+ LLSD::array_const_iterator iter = clipboard.beginArray();
+ LLSD::array_const_iterator end = clipboard.endArray();
+ for (; iter != end; ++iter)
+ {
+ const LLSD& te_data = *iter;
+ if (te_data.has("te") && te_data["te"].has("imageid"))
+ {
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ full_perm_object &= full_perm;
+ if (!full_perm)
+ {
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (!itemp)
+ {
+ // image might be in object's inventory, but it can be not up to date
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ else
+ {
+ // Item was not found on 'copy' stage
+ // Since this happened at copy, might be better to either show this
+ // at copy stage or to drop clipboard here
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ }
+
+ if (!full_perm_object)
+ {
+ LLNotificationsUtil::add("FacePasteTexturePermissions");
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(true, true);
+ selected_objects->applyToObjects(&sendfunc);
+
+ LLPanelFaceNavigateHomeFunctor navigate_home_func;
+ selected_objects->applyToTEs(&navigate_home_func);
+}
+
+void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
+{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Texture
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean();
+ if (te_data["te"].has("imageid"))
+ {
+ const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id
+ LLViewerInventoryItem* itemp_res = NULL;
+
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ itemp_res = itemp;
+ }
+ else
+ {
+ // Theoretically shouldn't happend, but if it does happen, we
+ // might need to add a notification to user that paste will fail
+ // since inventory isn't fully loaded
+ LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL;
+ }
+ }
+ }
+ // for case when item got removed from inventory after we pressed 'copy'
+ // or texture got pasted into previous object
+ if (!itemp_res && !full_perm)
+ {
+ // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable.
+ LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL;
+ // Todo: fix this, we are often searching same texture multiple times (equal to number of faces)
+ // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(imageid);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ // Extremely unreliable and perfomance unfriendly.
+ // But we need this to check permissions and it is how texture control finds items
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ itemp_res = itemp;
+ break; // first match
+ }
+ }
+ }
+ }
+
+ if (itemp_res)
+ {
+ if (te == -1) // all faces
+ {
+ LLToolDragAndDrop::dropTextureAllFaces(objectp,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null);
+ }
+ else // one face
+ {
+ LLToolDragAndDrop::dropTextureOneFace(objectp,
+ te,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null,
+ 0);
+ }
+ }
+ // not an inventory item or no complete items
+ else if (full_perm)
+ {
+ // Either library, local or existed as fullperm when user made a copy
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ objectp->setTEImage(U8(te), image);
+ }
+ }
+
+ if (te_data["te"].has("bumpmap"))
+ {
+ objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger());
+ }
+ if (te_data["te"].has("bumpshiny"))
+ {
+ objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger());
+ }
+ if (te_data["te"].has("bumpfullbright"))
+ {
+ objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
+ }
+ if (te_data["te"].has("pbr"))
+ {
+ objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false);
+ }
+ else
+ {
+ objectp->setRenderMaterialID(te, LLUUID::null, false);
+ }
+
+ // Texture map
+ if (te_data["te"].has("scales") && te_data["te"].has("scalet"))
+ {
+ objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal());
+ }
+ if (te_data["te"].has("offsets") && te_data["te"].has("offsett"))
+ {
+ objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal());
+ }
+ if (te_data["te"].has("imagerot"))
+ {
+ objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal());
+ }
+
+ // Media
+ if (te_data["te"].has("media_flags"))
+ {
+ U8 media_flags = te_data["te"]["media_flags"].asInteger();
+ objectp->setTEMediaFlags(te, media_flags);
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(objectp);
+ if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY))
+ {
+ vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ else
+ {
+ // Keep media flags on destination unchanged
+ }
+ }
+
+ if (te_data.has("material"))
+ {
+ LLUUID object_id = objectp->getID();
+
+ LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+
+ // Normal
+ // Replace placeholders with target's
+ if (te_data["material"].has("NormMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getNormalID();
+ if (id.notNull())
+ {
+ te_data["material"]["NormMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id);
+
+ // Specular
+ // Replace placeholders with target's
+ if (te_data["material"].has("SpecMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getSpecularID();
+ if (id.notNull())
+ {
+ te_data["material"]["SpecMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id);
+ LLColor4 spec_color(te_data["material"]["SpecColor"]);
+ LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
+ LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+ if (te_data.has("te") && te_data["te"].has("shiny"))
+ {
+ objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
+ }
+ }
+ }
+}
+
+void LLPanelFace::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "color_paste")
+ {
+ onPasteColor();
+ }
+ else if (command == "texture_paste")
+ {
+ onPasteTexture();
+ }
+ // copy
+ else if (command == "color_copy")
+ {
+ onCopyColor();
+ }
+ else if (command == "texture_copy")
+ {
+ onCopyTexture();
+ }
+}
+
+bool LLPanelFace::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "color_paste")
+ {
+ return mClipboardParams.has("color");
+ }
+ else if (command == "texture_paste")
+ {
+ return mClipboardParams.has("texture");
+ }
+ return false;
+}
+
+
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
@@ -2607,6 +4547,50 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
}
}
+void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+ if (can_copy && can_transfer)
+ {
+ pbr_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ pbr_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailable");
+ }
+ }
+}
+
+void LLPanelFace::onPbrStartEditing()
+{
+ bool identical;
+ LLUUID material_id;
+ LLSelectedTE::getPbrMaterialId(material_id, identical);
+
+ LL_DEBUGS() << "loading material live editor with asset " << material_id << LL_ENDL;
+
+ LLMaterialEditor::loadLive();
+}
+
bool LLPanelFace::isIdenticalPlanarTexgen()
{
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
@@ -2686,6 +4670,18 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
}
+void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical)
+{
+ struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ return object->getRenderMaterialID(te_index);
+ }
+ } func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, id);
+}
+
void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
{
struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
@@ -2824,3 +4820,4 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic
} max_diff_repeats_func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
}
+
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 2d57d89a44..cc46116545 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,8 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
+class LLMediaCtrl;
+class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
@@ -97,8 +99,10 @@ public:
virtual ~LLPanelFace();
void refresh();
- void setMediaURL(const std::string& url);
- void setMediaType(const std::string& mime_type);
+ void refreshMedia();
+ void unloadMedia();
+
+ /*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
{
@@ -114,6 +118,12 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
protected:
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
void getState();
void sendTexture(); // applies and sends texture
@@ -125,9 +135,15 @@ protected:
void sendShiny(U32 shininess); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
void sendGlow();
- void sendMedia();
void alignTestureLayer();
+ void updateCopyTexButton();
+
+ void onCommitPbr(const LLSD& data);
+ void onCancelPbr(const LLSD& data);
+ void onSelectPbr(const LLSD& data);
+ static BOOL onDragPbr(LLUICtrl* ctrl, LLInventoryItem* item);
+
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
@@ -150,6 +166,9 @@ protected:
void onCloseTexturePicker(const LLSD& data);
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
+
// Make UI reflect state of currently selected material (refresh)
// and UI mode (e.g. editing normal map v diffuse map)
//
@@ -191,9 +210,14 @@ protected:
static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onCommitPbrType(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -205,6 +229,18 @@ protected:
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
+public: // needs to be accessible to selection manager
+ void onCopyColor(); // records all selected faces
+ void onPasteColor(); // to specific face
+ void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face
+ void onCopyTexture();
+ void onPasteTexture();
+ void onPasteTexture(LLViewerObject* objectp, S32 te);
+
+protected:
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
static F32 valueGlow(LLViewerObject* object, S32 face);
@@ -234,6 +270,10 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
+ LLComboBox *mComboMatMedia;
+ LLMediaCtrl *mTitleMedia;
+ LLTextBox *mTitleMediaText;
+
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@@ -241,10 +281,6 @@ private:
//
void updateVisibility();
- // Make material(s) reflect current state of UI (apply edit)
- //
- void updateMaterial();
-
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -400,7 +436,12 @@ private:
* If agent selects texture which is not allowed to be applied for the currently selected object,
* all controls of the floater texture picker which allow to apply the texture will be disabled.
*/
- void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onPbrSelectionChanged(LLInventoryItem* itemp);
+ void onPbrStartEditing();
+
+ LLMenuButton* mMenuClipboardColor;
+ LLMenuButton* mMenuClipboardTexture;
bool mIsAlpha;
@@ -415,7 +456,12 @@ private:
* up-arrow on a spinner, and avoids running afoul of its throttle.
*/
bool mUpdateInFlight;
- bool mUpdatePending;
+ bool mUpdatePending;
+
+ LLSD mClipboardParams;
+
+ LLSD mMediaSettings;
+ bool mNeedMediaTitle;
public:
#if defined(DEF_GET_MAT_STATE)
@@ -497,6 +543,7 @@ public:
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
+ DEF_EDIT_MAT_STATE(LLUUID, const LLUUID&, setMaterialID);
};
class LLSelectedTE
@@ -506,6 +553,7 @@ public:
static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
static void getTexId(LLUUID& id, bool& identical);
+ static void getPbrMaterialId(LLUUID& id, bool& identical);
static void getObjectScaleS(F32& scale_s, bool& identical);
static void getObjectScaleT(F32& scale_t, bool& identical);
static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 375daf60f8..04d3236bf1 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -97,6 +97,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mEditCharter->setCommitCallback(onCommitAny, this);
mEditCharter->setFocusReceivedCallback(boost::bind(onFocusEdit, _1, this));
mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
+ mEditCharter->setContentTrusted(false);
}
// Options
@@ -575,7 +576,8 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
if (mEditCharter)
{
- mEditCharter->setText(gdatap->mCharter);
+ mEditCharter->setParseURLs(!mAllowEdit || !can_change_ident);
+ mEditCharter->setText(gdatap->mCharter);
}
resetDirty();
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index ab32ea3956..82f880c9ee 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 389baa86cd..07a8641a92 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,6 +1,6 @@
/**
- * @file llpanelavatar.cpp
- * @brief LLPanelAvatar and related class implementations
+ * @file llpanelimcontrolpanel.cpp
+ * @brief LLPanelIMControlPanel and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..9e3fc54477 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild()
mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check");
childSetCommitCallback("group av sound check", onCommitAny, this);
+ mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap");
+ childSetCommitCallback("obscure_moap", onCommitAny, this);
+
return TRUE;
}
@@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh()
mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on
mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off
+
+ mCheckObscureMOAP->set(parcel->getObscureMOAP());
+ mCheckObscureMOAP->setEnabled(can_change_media);
}
}
// static
@@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
group_av_sound = self->mCheckAVSoundGroup->get();
}
+ bool obscure_moap = self->mCheckObscureMOAP->get();
+
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
@@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMusicURL(music_url);
parcel->setAllowAnyAVSounds(any_av_sound);
parcel->setAllowGroupAVSounds(group_av_sound);
+ parcel->setObscureMOAP(obscure_moap);
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 7e4fce80e4..b54fe62179 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -53,6 +53,7 @@ private:
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mCheckAVSoundAny;
LLCheckBoxCtrl* mCheckAVSoundGroup;
+ LLCheckBoxCtrl* mCheckObscureMOAP;
LLSafeHandle<LLParcelSelection>& mParcel;
};
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce17da3076..c3334605ae 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
+#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
return can_be_modified;
}
-void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
-{
- pick_panel->setVisible(FALSE);
- owner->removeChild(pick_panel);
- //we need remove observer to avoid processParcelInfo in the future.
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
-
- delete pick_panel;
- pick_panel = NULL;
-}
-
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
*accept = ACCEPT_NO;
@@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
LLVector3d landmark_global_pos;
landmark->getGlobalPos(landmark_global_pos);
- // let's toggle pick panel into panel places
- LLPanel* panel_places = NULL;
- LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places");
- if (floaterp)
- {
- panel_places = floaterp->findChild<LLPanel>("main_panel");
- }
-
- if (!panel_places)
- {
- llassert(NULL != panel_places);
- return;
- }
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
LLPickData data;
data.pos_global = landmark_global_pos;
data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
-
- LLSD params;
- params["parcel_id"] = parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index d7408269b5..16f3a5dc24 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
-#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@@ -136,7 +135,6 @@ private:
* For now it checks cut/rename/delete/paste actions.
*/
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
- void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 381b80fb66..9df3a8e31a 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -92,44 +92,6 @@ LLPointer<LLCredential> load_user_credentials(std::string &user_key)
}
}
-// keys are lower case to be case insensitive so they are not always
-// identical to names which retain user input, like:
-// "AwEsOmE Resident" -> "awesome_resident"
-std::string get_user_key_from_name(const std::string &username)
-{
- std::string key = username;
- LLStringUtil::trim(key);
- LLStringUtil::toLower(key);
- if (!LLGridManager::getInstance()->isSystemGrid())
- {
- size_t separator_index = username.find_first_of(" ");
- if (separator_index == username.npos)
- {
- // CRED_IDENTIFIER_TYPE_ACCOUNT
- return key;
- }
- }
- // CRED_IDENTIFIER_TYPE_AGENT
- size_t separator_index = username.find_first_of(" ._");
- std::string first = username.substr(0, separator_index);
- std::string last;
- if (separator_index != username.npos)
- {
- last = username.substr(separator_index + 1, username.npos);
- LLStringUtil::trim(last);
- }
- else
- {
- // ...on Linden grids, single username users as considered to have
- // last name "Resident"
- // *TODO: Make login.cgi support "account_name" like above
- last = "resident";
- }
-
- key = first + "_" + last;
- return key;
-}
-
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@@ -361,11 +323,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setKeystrokeOnEsc(TRUE);
- if (!mFirstLoginThisInstall)
- {
- LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
- remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
- }
+
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
+ getChild<LLCheckBoxCtrl>("remember_password")->setCommitCallback(boost::bind(&LLPanelLogin::onRememberPasswordCheck, this));
}
void LLPanelLogin::addFavoritesToStartLocation()
@@ -438,10 +399,22 @@ void LLPanelLogin::addFavoritesToStartLocation()
combo->addSeparator();
LL_DEBUGS() << "Loading favorites for " << iter->first << LL_ENDL;
LLSD user_llsd = iter->second;
+ bool update_password_setting = true;
for (LLSD::array_const_iterator iter1 = user_llsd.beginArray();
iter1 != user_llsd.endArray(); ++iter1)
{
- std::string label = (*iter1)["name"].asString();
+ if ((*iter1).has("save_password"))
+ {
+ bool save_password = (*iter1)["save_password"].asBoolean();
+ gSavedSettings.setBOOL("RememberPassword", save_password);
+ if (!save_password)
+ {
+ getChild<LLButton>("connect_btn")->setEnabled(false);
+ }
+ update_password_setting = false;
+ }
+
+ std::string label = (*iter1)["name"].asString();
std::string value = (*iter1)["slurl"].asString();
if(label != "" && value != "")
{
@@ -453,6 +426,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
}
}
}
+ if (update_password_setting)
+ {
+ gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
+ }
break;
}
if (combo->getValue().asString().empty())
@@ -565,21 +542,12 @@ void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remem
LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
return;
}
- if (sInstance->mFirstLoginThisInstall)
- {
- LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
- remember_check->setValue(remember_psswrd);
- // no list to populate
- setFields(credential);
- }
- else
- {
- sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
- LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
- remember_password->setValue(remember_user && remember_psswrd);
- remember_password->setEnabled(remember_user);
- sInstance->populateUserList(credential);
- }
+
+ sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
+ LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
+ remember_password->setValue(remember_user && remember_psswrd);
+ remember_password->setEnabled(remember_user);
+ sInstance->populateUserList(credential);
}
//static
@@ -690,39 +658,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
size_t separator_index = username.find_first_of(' ');
- if (separator_index == username.npos
- && !LLGridManager::getInstance()->isSystemGrid())
- {
- LL_INFOS("Credentials", "Authentication") << "account: " << username << LL_ENDL;
- // single username, so this is a 'clear' identifier
- identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
- identifier["account_name"] = username;
-
- if (LLPanelLogin::sInstance->mPasswordModified)
- {
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- else
- {
- credential = load_user_credentials(username);
- if (credential.notNull())
- {
- authenticator = credential->getAuthenticator();
- if (authenticator.emptyMap())
- {
- // Likely caused by user trying to log in to non-system grid
- // with unsupported name format, just retry
- LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
- // password is plaintext
- authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
- authenticator["secret"] = password;
- }
- }
- }
- }
- else
{
// Be lenient in terms of what separators we allow for two-word names
// and allow legacy users to login with firstname.lastname
@@ -773,16 +708,9 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
- if (!sInstance->mFirstLoginThisInstall)
- {
- remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
- remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
- }
- else
- {
- remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
- remember_user = remember_psswrd; // on panel_login_first "remember_check" is named as 'remember me'
- }
+
+ remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
+ remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
}
@@ -1145,17 +1073,18 @@ void LLPanelLogin::onUserListCommit(void*)
}
// static
-// At the moment only happens if !mFirstLoginThisInstall
void LLPanelLogin::onRememberUserCheck(void*)
{
- if (sInstance && !sInstance->mFirstLoginThisInstall)
+ if (sInstance)
{
LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name"));
LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_password"));
LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));
bool remember = remember_name->getValue().asBoolean();
- if (user_combo->getCurrentIndex() != -1 && !remember)
+ if (!sInstance->mFirstLoginThisInstall
+ && user_combo->getCurrentIndex() != -1
+ && !remember)
{
remember = true;
remember_name->setValue(true);
@@ -1169,6 +1098,14 @@ void LLPanelLogin::onRememberUserCheck(void*)
}
}
+void LLPanelLogin::onRememberPasswordCheck(void*)
+{
+ if (sInstance)
+ {
+ gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
+ }
+}
+
// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c5e6b41def..c6254f72cf 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -107,6 +107,7 @@ private:
static void onUserNameTextEnty(void*);
static void onUserListCommit(void*);
static void onRememberUserCheck(void*);
+ static void onRememberPasswordCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
diff --git a/indra/newview/llpanelloginlistener.cpp b/indra/newview/llpanelloginlistener.cpp
index 33efde11f3..fb3e8dc244 100644
--- a/indra/newview/llpanelloginlistener.cpp
+++ b/indra/newview/llpanelloginlistener.cpp
@@ -47,5 +47,5 @@ LLPanelLoginListener::LLPanelLoginListener(LLPanelLogin* instance):
void LLPanelLoginListener::onClickConnect(const LLSD&) const
{
- mPanel->onClickConnect(NULL);
+ mPanel->onClickConnect(false);
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 89256b40c4..49562da3f7 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -919,6 +919,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@@ -975,6 +976,12 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
+ if (!getChild<LLUICtrl>("check_material")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
+ filtered_by_all_types = FALSE;
+ }
+
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@@ -1129,6 +1136,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
@@ -1149,6 +1157,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
deleted file mode 100644
index 55e4ffff5e..0000000000
--- a/indra/newview/llpanelme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelme.cpp
- * @brief Side tray "Me" (My Profile) panel
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelme.h"
-
-// Viewer includes
-#include "llpanelprofile.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llhints.h"
-#include "llviewercontrol.h"
-
-// Linden libraries
-#include "llavatarnamecache.h" // IDEVO
-#include "lliconctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h" // IDEVO
-#include "lltabcontainer.h"
-#include "lltexturectrl.h"
-
-static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
-
-LLPanelMe::LLPanelMe(void)
- : LLPanelProfile()
-{
- setAvatarId(gAgent.getID());
-}
-
-BOOL LLPanelMe::postBuild()
-{
- LLPanelProfile::postBuild();
-
- return TRUE;
-}
-
-void LLPanelMe::onOpen(const LLSD& key)
-{
- LLPanelProfile::onOpen(key);
-}
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 9730f0f16d..e1818cc68b 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
- // interrogates controls and updates widgets as required
- updateMediaPreview();
-
return true;
}
@@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
-
- // interrogates controls and updates widgets as required
- self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 831c89b005..0bfc1297d3 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -46,6 +46,7 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -117,8 +118,9 @@ BOOL LLPanelObject::postBuild()
// Phantom checkbox
mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
-
+
// Position
+ mMenuClipboardPos = getChild<LLMenuButton>("clipboard_pos_btn");
mLabelPosition = getChild<LLTextBox>("label position");
mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
childSetCommitCallback("Pos X",onCommitPosition,this);
@@ -128,6 +130,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Pos Z",onCommitPosition,this);
// Scale
+ mMenuClipboardSize = getChild<LLMenuButton>("clipboard_size_btn");
mLabelSize = getChild<LLTextBox>("label size");
mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
childSetCommitCallback("Scale X",onCommitScale,this);
@@ -141,6 +144,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Scale Z",onCommitScale,this);
// Rotation
+ mMenuClipboardRot = getChild<LLMenuButton>("clipboard_rot_btn");
mLabelRotation = getChild<LLTextBox>("label rotation");
mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
childSetCommitCallback("Rot X",onCommitRotation,this);
@@ -155,6 +159,8 @@ BOOL LLPanelObject::postBuild()
mComboBaseType = getChild<LLComboBox>("comboBaseType");
childSetCommitCallback("comboBaseType",onCommitParametric,this);
+ mMenuClipboardParams = getChild<LLMenuButton>("clipboard_obj_params_btn");
+
// Cut
mLabelCut = getChild<LLTextBox>("text cut");
mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
@@ -285,8 +291,13 @@ LLPanelObject::LLPanelObject()
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
mSculptTypeRevert(0),
+ mHasClipboardPos(false),
+ mHasClipboardSize(false),
+ mHasClipboardRot(false),
mSizeChanged(FALSE)
{
+ mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelObject.menuEnable", boost::bind(&LLPanelObject::menuEnableItem, this, _2));
}
@@ -373,7 +384,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_POS);
}
-
+ mMenuClipboardPos->setEnabled(enable_move);
mLabelPosition->setEnabled( enable_move );
mCtrlPosX->setEnabled(enable_move);
mCtrlPosY->setEnabled(enable_move);
@@ -399,6 +410,7 @@ void LLPanelObject::getState( )
calcp->setVar(LLCalc::Z_SCALE, 0.f);
}
+ mMenuClipboardSize->setEnabled(enable_scale);
mLabelSize->setEnabled( enable_scale );
mCtrlScaleX->setEnabled( enable_scale );
mCtrlScaleY->setEnabled( enable_scale );
@@ -430,6 +442,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_ROT);
}
+ mMenuClipboardRot->setEnabled(enable_rotate);
mLabelRotation->setEnabled( enable_rotate );
mCtrlRotX->setEnabled( enable_rotate );
mCtrlRotY->setEnabled( enable_rotate );
@@ -607,7 +620,7 @@ void LLPanelObject::getState( )
}
else
{
- LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
selected_item = MI_BOX;
}
@@ -933,6 +946,7 @@ void LLPanelObject::getState( )
// Update field enablement
mComboBaseType ->setEnabled( enabled );
+ mMenuClipboardParams->setEnabled(enabled);
mLabelCut ->setEnabled( enabled );
mSpinCutBegin ->setEnabled( enabled );
@@ -1093,7 +1107,8 @@ void LLPanelObject::getState( )
}
mComboBaseType->setEnabled(!isMesh);
-
+ mMenuClipboardParams->setEnabled(!isMesh);
+
if (mCtrlSculptType)
{
if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
@@ -1157,11 +1172,11 @@ void LLPanelObject::sendIsPhysical()
LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
mIsPhysical = value;
- LL_INFOS() << "update physics sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update physics not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL;
}
}
@@ -1173,11 +1188,11 @@ void LLPanelObject::sendIsTemporary()
LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
mIsTemporary = value;
- LL_INFOS() << "update temporary sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update temporary not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL;
}
}
@@ -1190,11 +1205,11 @@ void LLPanelObject::sendIsPhantom()
LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
mIsPhantom = value;
- LL_INFOS() << "update phantom sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update phantom not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL;
}
}
@@ -1304,7 +1319,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
break;
default:
- LL_WARNS() << "Unknown base type " << selected_type
+ LL_WARNS("FloaterTools") << "Unknown base type " << selected_type
<< " in getVolumeParams()" << LL_ENDL;
// assume a box
selected_type = MI_BOX;
@@ -1644,13 +1659,15 @@ void LLPanelObject::sendPosition(BOOL btn_down)
LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
LLViewerRegion* regionp = mObject->getRegion();
- // Clamp the Z height
- const F32 height = newpos.mV[VZ];
- const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
- const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+ if (!regionp) return;
if (!mObject->isAttachment())
{
+ // Clamp the Z height
+ const F32 height = newpos.mV[VZ];
+ const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
+ const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+
if ( height < min_height)
{
newpos.mV[VZ] = min_height;
@@ -1672,8 +1689,19 @@ void LLPanelObject::sendPosition(BOOL btn_down)
// Make sure new position is in a valid region, so the object
// won't get dumped by the simulator.
LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
-
- if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
+ bool is_valid_pos = true;
+ if (mObject->isAttachment())
+ {
+ LLVector3 delta_pos = mObject->getPositionEdit() - newpos;
+ LLVector3d attachment_pos = regionp->getPosGlobalFromRegion(mObject->getPositionRegion() + delta_pos);
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(attachment_pos);
+ }
+ else
+ {
+ is_valid_pos = LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global);
+ }
+
+ if (is_valid_pos)
{
// send only if the position is changed, that is, the delta vector is not zero
LLVector3d old_pos_global = mObject->getPositionGlobal();
@@ -2000,3 +2028,283 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
self->sendSculpt();
}
+
+void LLPanelObject::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "psr_paste")
+ {
+ onPastePos();
+ onPasteSize();
+ onPasteRot();
+ }
+ else if (command == "pos_paste")
+ {
+ onPastePos();
+ }
+ else if (command == "size_paste")
+ {
+ onPasteSize();
+ }
+ else if (command == "rot_paste")
+ {
+ onPasteRot();
+ }
+ else if (command == "params_paste")
+ {
+ onPasteParams();
+ }
+ // copy
+ else if (command == "psr_copy")
+ {
+ onCopyPos();
+ onCopySize();
+ onCopyRot();
+ }
+ else if (command == "pos_copy")
+ {
+ onCopyPos();
+ }
+ else if (command == "size_copy")
+ {
+ onCopySize();
+ }
+ else if (command == "rot_copy")
+ {
+ onCopyRot();
+ }
+ else if (command == "params_copy")
+ {
+ onCopyParams();
+ }
+}
+
+bool LLPanelObject::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "psr_paste")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot;
+ }
+ else if (command == "pos_paste")
+ {
+ // assumes that menu won't be active if there is no move permission
+ return mHasClipboardPos;
+ }
+ else if (command == "size_paste")
+ {
+ return mHasClipboardSize;
+ }
+ else if (command == "rot_paste")
+ {
+ return mHasClipboardRot;
+ }
+ else if (command == "params_paste")
+ {
+ return mClipboardParams.isMap() && !mClipboardParams.emptyMap();
+ }
+ // copy options
+ else if (command == "psr_copy")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ // since we forbid seeing values we also should forbid copying them
+ return enable_move && enable_modify;
+ }
+ return false;
+}
+
+void LLPanelObject::onCopyPos()
+{
+ mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardPos = true;
+}
+
+void LLPanelObject::onCopySize()
+{
+ mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardSize = true;
+}
+
+void LLPanelObject::onCopyRot()
+{
+ mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardRot = true;
+}
+
+void LLPanelObject::onPastePos()
+{
+ if (!mHasClipboardPos) return;
+ if (mObject.isNull()) return;
+
+ LLViewerRegion* regionp = mObject->getRegion();
+ if (!regionp) return;
+
+
+ // Clamp pos on non-attachments, just keep the prims within the region
+ if (!mObject->isAttachment())
+ {
+ F32 max_width = regionp->getWidth(); // meters
+ mClipboardPos.mV[VX] = llclamp(mClipboardPos.mV[VX], 0.f, max_width);
+ mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
+ //height will get properly clamped by sendPosition
+ }
+
+ mCtrlPosX->set( mClipboardPos.mV[VX] );
+ mCtrlPosY->set( mClipboardPos.mV[VY] );
+ mCtrlPosZ->set( mClipboardPos.mV[VZ] );
+
+ sendPosition(FALSE);
+}
+
+void LLPanelObject::onPasteSize()
+{
+ if (!mHasClipboardSize) return;
+
+ mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+
+ mCtrlScaleX->set(mClipboardSize.mV[VX]);
+ mCtrlScaleY->set(mClipboardSize.mV[VY]);
+ mCtrlScaleZ->set(mClipboardSize.mV[VZ]);
+
+ sendScale(FALSE);
+}
+
+void LLPanelObject::onPasteRot()
+{
+ if (!mHasClipboardRot) return;
+
+ mCtrlRotX->set(mClipboardRot.mV[VX]);
+ mCtrlRotY->set(mClipboardRot.mV[VY]);
+ mCtrlRotZ->set(mClipboardRot.mV[VZ]);
+
+ sendRotation(FALSE);
+}
+
+void LLPanelObject::onCopyParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || objectp->isMesh())
+ {
+ return;
+ }
+
+ mClipboardParams.clear();
+
+ // Parametrics
+ LLVolumeParams params;
+ getVolumeParams(params);
+ mClipboardParams["volume_params"] = params.asLLSD();
+
+ // Sculpted Prim
+ if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
+ {
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
+ }
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ }
+}
+
+void LLPanelObject::onPasteParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ // Sculpted Prim
+ if (mClipboardParams.has("sculpt"))
+ {
+ LLSculptParams sculpt_params;
+ LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID();
+ U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger();
+ sculpt_params.setSculptTexture(sculpt_id, sculpt_type);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+ }
+ else
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ {
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+ }
+ }
+
+ // volume params
+ // make sure updateVolume() won't affect flexible
+ if (mClipboardParams.has("volume_params"))
+ {
+ LLVolumeParams params;
+ params.fromLLSD(mClipboardParams["volume_params"]);
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->isFlexible())
+ {
+ if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE);
+ }
+ }
+ else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_LINE);
+ }
+
+ objectp->updateVolume(params);
+ }
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 8829f493fa..515dd27c0a 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -66,6 +67,14 @@ public:
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
static void onCommitPhysics( LLUICtrl* ctrl, void* userdata);
+ void onCopyPos();
+ void onPastePos();
+ void onCopySize();
+ void onPasteSize();
+ void onCopyRot();
+ void onPasteRot();
+ void onCopyParams();
+ void onPasteParams();
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
@@ -75,6 +84,9 @@ public:
BOOL onDropSculpt(LLInventoryItem* item);
static void onCommitSculptType( LLUICtrl *ctrl, void* userdata);
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
protected:
void getState();
@@ -92,6 +104,7 @@ protected:
protected:
// Per-object options
LLComboBox* mComboBaseType;
+ LLMenuButton* mMenuClipboardParams;
LLTextBox* mLabelCut;
LLSpinCtrl* mSpinCutBegin;
@@ -131,17 +144,20 @@ protected:
LLTextBox* mLabelRevolutions;
LLSpinCtrl* mSpinRevolutions;
+ LLMenuButton* mMenuClipboardPos;
LLTextBox* mLabelPosition;
LLSpinCtrl* mCtrlPosX;
LLSpinCtrl* mCtrlPosY;
LLSpinCtrl* mCtrlPosZ;
+ LLMenuButton* mMenuClipboardSize;
LLTextBox* mLabelSize;
LLSpinCtrl* mCtrlScaleX;
LLSpinCtrl* mCtrlScaleY;
LLSpinCtrl* mCtrlScaleZ;
BOOL mSizeChanged;
+ LLMenuButton* mMenuClipboardRot;
LLTextBox* mLabelRotation;
LLSpinCtrl* mCtrlRotX;
LLSpinCtrl* mCtrlRotY;
@@ -157,7 +173,7 @@ protected:
LLComboBox *mCtrlSculptType;
LLCheckBoxCtrl *mCtrlSculptMirror;
LLCheckBoxCtrl *mCtrlSculptInvert;
-
+
LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed
BOOL mIsPhysical; // to avoid sending "physical" when not changed
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
@@ -167,6 +183,15 @@ protected:
LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
U8 mSculptTypeRevert; // so we can revert the sculpt type on cancel
+ LLVector3 mClipboardPos;
+ LLVector3 mClipboardSize;
+ LLVector3 mClipboardRot;
+ LLSD mClipboardParams;
+
+ bool mHasClipboardPos;
+ bool mHasClipboardSize;
+ bool mHasClipboardRot;
+
LLPointer<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
};
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 0d987df6ca..d61cc26f62 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -50,6 +50,7 @@
#include "llinventoryicon.h"
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
+#include "llmaterialeditor.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -618,7 +619,18 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- mDisplayName.assign(cat->getName());
+ std::string name = cat->getName();
+ if (mChildren.size() > 0)
+ {
+ // Add item count
+ // Normally we would be using getLabelSuffix for this
+ // but object's inventory just uses displaynames
+ LLStringUtil::format_map_t args;
+ args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size());
+
+ name.append(" " + LLTrans::getString("InventoryItemsCount", args));
+ }
+ mDisplayName.assign(name);
}
return mDisplayName;
@@ -704,6 +716,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{
@@ -1151,6 +1164,58 @@ LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
}
///----------------------------------------------------------------------------
+/// Class LLTaskMaterialBridge
+///----------------------------------------------------------------------------
+
+class LLTaskMaterialBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskMaterialBridge(LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name) :
+ LLTaskInvFVBridge(panel, uuid, name) {}
+
+ BOOL canOpenItem() const override { return TRUE; }
+ void openItem() override;
+ BOOL removeItem() override;
+};
+
+void LLTaskMaterialBridge::openItem()
+{
+ LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
+ if(!object || object->isInventoryPending())
+ {
+ return;
+ }
+
+ // Note: even if we are not allowed to modify copyable notecard, we should be able to view it
+ LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
+ BOOL item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
+ if( item_copy
+ || object->permModify()
+ || gAgent.isGodlike())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = mPanel->getTaskUUID();
+ floater_key["itemid"] = mUUID;
+ LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (mat)
+ {
+ mat->setObjectID(mPanel->getTaskUUID());
+ mat->openFloater(floater_key);
+ mat->setFocus(TRUE);
+ }
+ }
+}
+
+BOOL LLTaskMaterialBridge::removeItem()
+{
+ LLFloaterReg::hideInstance("material_editor", LLSD(mUUID));
+ return LLTaskInvFVBridge::removeItem();
+}
+
+
+///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1237,6 +1302,11 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_name,
itemflags);
break;
+ case LLAssetType::AT_MATERIAL:
+ new_bridge = new LLTaskMaterialBridge(panel,
+ object_id,
+ object_name);
+ break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
@@ -1522,6 +1592,8 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
{
createViewsForCategory(&contents, inventory_root, new_folder);
}
+ // Refresh for label to add item count
+ new_folder->refresh();
}
}
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
deleted file mode 100644
index 40326cfb39..0000000000
--- a/indra/newview/llpanelpick.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/**
- * @file llpanelpick.cpp
- * @brief LLPanelPick class implementation
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "message.h"
-
-#include "llparcel.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h"
-#include "lltexteditor.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloaterworldmap.h"
-#include "lltexturectrl.h"
-#include "lluiconstants.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llworldmap.h"
-
-
-#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
-#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
-
-#define XML_NAME "pick_name"
-#define XML_DESC "pick_desc"
-#define XML_SNAPSHOT "pick_snapshot"
-#define XML_LOCATION "pick_location"
-
-#define XML_BTN_ON_TXTR "edit_icon"
-#define XML_BTN_SAVE "save_changes_btn"
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickInfo* LLPanelPickInfo::create()
-{
- LLPanelPickInfo* panel = new LLPanelPickInfo();
- panel->buildFromFile(XML_PANEL_PICK_INFO);
- return panel;
-}
-
-LLPanelPickInfo::LLPanelPickInfo()
- : LLPanel()
- , LLAvatarPropertiesObserver()
- , LLRemoteParcelInfoObserver()
- , mAvatarId(LLUUID::null)
- , mSnapshotCtrl(NULL)
- , mPickId(LLUUID::null)
- , mParcelId(LLUUID::null)
- , mRequestedId(LLUUID::null)
- , mScrollingPanelMinHeight(0)
- , mScrollingPanelWidth(0)
- , mScrollingPanel(NULL)
- , mScrollContainer(NULL)
-{
-}
-
-LLPanelPickInfo::~LLPanelPickInfo()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::onOpen(const LLSD& key)
-{
- LLUUID avatar_id = key["avatar_id"];
- if(avatar_id.isNull())
- {
- return;
- }
-
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(
- getAvatarId(), this);
- }
-
- setAvatarId(avatar_id);
-
- resetData();
- resetControls();
-
- setPickId(key["pick_id"]);
- setPickName(key["pick_name"]);
- setPickDesc(key["pick_desc"]);
- setSnapshotId(key["snapshot_id"]);
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(
- getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
- getAvatarId(), getPickId());
-}
-
-BOOL LLPanelPickInfo::postBuild()
-{
- mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
-
- childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
- childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
- childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
-
- mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
- mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
-
- mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
- mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
-
- LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
- text_desc->setContentTrusted(false);
-
- return TRUE;
-}
-
-void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
-
- if (!mScrollContainer || !mScrollingPanel)
- return;
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- S32 scroll_height = mScrollContainer->getRect().getHeight();
- if (mScrollingPanelMinHeight >= scroll_height)
- {
- mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
- }
- else
- {
- mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
- }
-}
-
-void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICK_INFO != type)
- {
- return;
- }
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if(!pick_info
- || pick_info->creator_id != getAvatarId()
- || pick_info->pick_id != getPickId())
- {
- return;
- }
-
- mParcelId = pick_info->parcel_id;
- setSnapshotId(pick_info->snapshot_id);
- setPickName(pick_info->name);
- setPickDesc(pick_info->desc);
- setPosGlobal(pick_info->pos_global);
-
- // Send remote parcel info request to get parcel name and sim (region) name.
- sendParcelInfoRequest();
-
- // *NOTE dzaporozhan
- // We want to keep listening to APT_PICK_INFO because user may
- // edit the Pick and we have to update Pick info panel.
- // revomeObserver is called from onClickBack
-}
-
-void LLPanelPickInfo::sendParcelInfoRequest()
-{
- if (mParcelId != mRequestedId)
- {
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
-
- mRequestedId = mParcelId;
- }
-}
-
-void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
-{
- setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
- parcel_data.sim_name, getPosGlobal()));
-
- // We have received parcel info for the requested ID so clear it now.
- mRequestedId.setNull();
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
-// PROTECTED AREA
-
-void LLPanelPickInfo::resetControls()
-{
- if(getAvatarId() == gAgent.getID())
- {
- getChildView("edit_btn")->setEnabled(TRUE);
- getChildView("edit_btn")->setVisible( TRUE);
- }
- else
- {
- getChildView("edit_btn")->setEnabled(FALSE);
- getChildView("edit_btn")->setVisible( FALSE);
- }
-}
-
-void LLPanelPickInfo::resetData()
-{
- setPickName(LLStringUtil::null);
- setPickDesc(LLStringUtil::null);
- setPickLocation(LLStringUtil::null);
- setPickId(LLUUID::null);
- setSnapshotId(LLUUID::null);
- mPosGlobal.clearVec();
- mParcelId.setNull();
- mRequestedId.setNull();
-}
-
-// static
-std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
-{
- std::string location_text;
- location_text.append(owner_name);
- if (!original_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(original_name);
-
- }
- if (!sim_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(sim_name);
- }
-
- if (!location_text.empty()) location_text.append(" ");
-
- if (!pos_global.isNull())
- {
- S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- }
- return location_text;
-}
-
-void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
-{
- mSnapshotCtrl->setImageAssetID(id);
- mSnapshotCtrl->setValid(TRUE);
-}
-
-void LLPanelPickInfo::setPickName(const std::string& name)
-{
- getChild<LLUICtrl>(XML_NAME)->setValue(name);
-}
-
-void LLPanelPickInfo::setPickDesc(const std::string& desc)
-{
- getChild<LLUICtrl>(XML_DESC)->setValue(desc);
-}
-
-void LLPanelPickInfo::setPickLocation(const std::string& location)
-{
- getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
-}
-
-void LLPanelPickInfo::onClickMap()
-{
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-void LLPanelPickInfo::onClickTeleport()
-{
- if (!getPosGlobal().isExactlyZero())
- {
- gAgent.teleportViaLocation(getPosGlobal());
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- }
-}
-
-void LLPanelPickInfo::onClickBack()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickEdit* LLPanelPickEdit::create()
-{
- LLPanelPickEdit* panel = new LLPanelPickEdit();
- panel->buildFromFile(XML_PANEL_EDIT_PICK);
- return panel;
-}
-
-LLPanelPickEdit::LLPanelPickEdit()
- : LLPanelPickInfo()
- , mLocationChanged(false)
- , mNeedData(true)
- , mNewPick(false)
-{
-}
-
-LLPanelPickEdit::~LLPanelPickEdit()
-{
-}
-
-void LLPanelPickEdit::onOpen(const LLSD& key)
-{
- LLUUID pick_id = key["pick_id"];
- mNeedData = true;
-
- // creating new Pick
- if(pick_id.isNull())
- {
- mNewPick = true;
-
- setAvatarId(gAgent.getID());
-
- resetData();
- resetControls();
-
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
- std::string pick_name, pick_desc, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- parcel_id = parcel->getID();
- pick_name = parcel->getName();
- pick_desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setParcelID(parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
- setSnapshotId(snapshot_id);
- setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
-
- enableSaveButton(true);
- }
- // editing existing pick
- else
- {
- mNewPick = false;
- LLPanelPickInfo::onOpen(key);
-
- enableSaveButton(false);
- }
-
- resetDirty();
-}
-
-void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
-{
- if(!pick_data)
- {
- return;
- }
-
- mNeedData = false;
-
- setParcelID(pick_data->parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- setPosGlobal(pick_data->pos_global);
- setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
- pick_data->sim_name, pick_data->pos_global));
-}
-
-BOOL LLPanelPickEdit::postBuild()
-{
- LLPanelPickInfo::postBuild();
-
- mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
-
- childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
-
- initTexturePickerMouseEvents();
-
- return TRUE;
-}
-
-void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::resetDirty()
-{
- LLPanelPickInfo::resetDirty();
-
- getChild<LLLineEditor>("pick_name")->resetDirty();
- getChild<LLTextEditor>("pick_desc")->resetDirty();
- mSnapshotCtrl->resetDirty();
- mLocationChanged = false;
-}
-
-BOOL LLPanelPickEdit::isDirty() const
-{
- if( mNewPick
- || LLPanelPickInfo::isDirty()
- || mLocationChanged
- || mSnapshotCtrl->isDirty()
- || getChild<LLLineEditor>("pick_name")->isDirty()
- || getChild<LLTextEditor>("pick_desc")->isDirty())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// PROTECTED AREA
-
-void LLPanelPickEdit::sendUpdate()
-{
- LLPickData pick_data;
-
- // If we don't have a pick id yet, we'll need to generate one,
- // otherwise we'll keep overwriting pick_id 00000 in the database.
- if (getPickId().isNull())
- {
- getPickId().generate();
- }
-
- pick_data.agent_id = gAgent.getID();
- pick_data.session_id = gAgent.getSessionID();
- pick_data.pick_id = getPickId();
- pick_data.creator_id = gAgent.getID();;
-
- //legacy var need to be deleted
- pick_data.top_pick = FALSE;
- pick_data.parcel_id = mParcelId;
- pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
- pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
- pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
- pick_data.pos_global = getPosGlobal();
- pick_data.sort_order = 0;
- pick_data.enabled = TRUE;
-
- LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
-
- if(mNewPick)
- {
- // Assume a successful create pick operation, make new number of picks
- // available immediately. Actual number of picks will be requested in
- // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
- LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
- }
-}
-
-void LLPanelPickEdit::onSnapshotChanged()
-{
- enableSaveButton(true);
-}
-
-void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
-{
- enableSaveButton(isDirty());
-}
-
-void LLPanelPickEdit::resetData()
-{
- LLPanelPickInfo::resetData();
- mLocationChanged = false;
-}
-
-void LLPanelPickEdit::enableSaveButton(bool enable)
-{
- getChildView(XML_BTN_SAVE)->setEnabled(enable);
-}
-
-void LLPanelPickEdit::onClickSetLocation()
-{
- // Save location for later use.
- setPosGlobal(gAgent.getPositionGlobal());
-
- std::string parcel_name, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- mParcelId = parcel->getID();
- parcel_name = parcel->getName();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
-
- mLocationChanged = true;
- enableSaveButton(TRUE);
-}
-
-void LLPanelPickEdit::onClickSave()
-{
- sendUpdate();
-
- mLocationChanged = false;
-
- LLSD params;
- params["action"] = "save_new_pick";
- notifyParent(params);
-}
-
-std::string LLPanelPickEdit::getLocationNotice()
-{
- static std::string notice = getString("location_notice");
- return notice;
-}
-
-void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(mNeedData)
- {
- LLPanelPickInfo::processProperties(data, type);
- }
-}
-
-// PRIVATE AREA
-
-void LLPanelPickEdit::initTexturePickerMouseEvents()
-{
- text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
-
- text_icon->setVisible(FALSE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- text_icon->setVisible(TRUE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- text_icon->setVisible(FALSE);
-}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
deleted file mode 100644
index 7a8bd66fcf..0000000000
--- a/indra/newview/llpanelpick.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file llpanelpick.h
- * @brief LLPanelPick class definition
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#ifndef LL_LLPANELPICK_H
-#define LL_LLPANELPICK_H
-
-#include "llpanel.h"
-#include "llremoteparcelrequest.h"
-#include "llavatarpropertiesprocessor.h"
-
-class LLIconCtrl;
-class LLTextureCtrl;
-class LLScrollContainer;
-class LLMessageSystem;
-class LLAvatarPropertiesObserver;
-
-/**
- * Panel for displaying Pick Information - snapshot, name, description, etc.
- */
-class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
-{
- LOG_CLASS(LLPanelPickInfo);
-public:
-
- // Creates new panel
- static LLPanelPickInfo* create();
-
- virtual ~LLPanelPickInfo();
-
- /**
- * Initializes panel properties
- *
- * By default Pick will be created for current Agent location.
- * Use setPickData to change Pick properties.
- */
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /**
- * Sends remote parcel info request to resolve parcel name from its ID.
- */
- void sendParcelInfoRequest();
-
- /**
- * Sets "Back" button click callback
- */
- virtual void setExitCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Edit" button click callback
- */
- virtual void setEditPickCallback(const commit_callback_t& cb);
-
- //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
- /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
- /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
-
-protected:
-
- LLPanelPickInfo();
-
- /**
- * Resets Pick information
- */
- virtual void resetData();
-
- /**
- * Resets UI controls (visibility, values)
- */
- virtual void resetControls();
-
- /**
- * "Location text" is actually the owner name, the original
- * name that owner gave the parcel, and the location.
- */
- static std::string createLocationText(
- const std::string& owner_name,
- const std::string& original_name,
- const std::string& sim_name,
- const LLVector3d& pos_global);
-
- virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
- virtual LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sets snapshot id.
- *
- * Will mark snapshot control as valid if id is not null.
- * Will mark snapshot control as invalid if id is null. If null id is a valid value,
- * you have to manually mark snapshot is valid.
- */
- virtual void setSnapshotId(const LLUUID& id);
-
- virtual void setPickId(const LLUUID& id) { mPickId = id; }
- virtual LLUUID& getPickId() { return mPickId; }
-
- virtual void setPickName(const std::string& name);
-
- virtual void setPickDesc(const std::string& desc);
-
- virtual void setPickLocation(const std::string& location);
-
- virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
- virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
-
- /**
- * Callback for "Map" button, opens Map
- */
- void onClickMap();
-
- /**
- * Callback for "Teleport" button, teleports user to Pick location.
- */
- void onClickTeleport();
-
- void onClickBack();
-
-protected:
-
- S32 mScrollingPanelMinHeight;
- S32 mScrollingPanelWidth;
- LLScrollContainer* mScrollContainer;
- LLPanel* mScrollingPanel;
- LLTextureCtrl* mSnapshotCtrl;
-
- LLUUID mAvatarId;
- LLVector3d mPosGlobal;
- LLUUID mParcelId;
- LLUUID mPickId;
- LLUUID mRequestedId;
-};
-
-/**
- * Panel for creating/editing Pick.
- */
-class LLPanelPickEdit : public LLPanelPickInfo
-{
- LOG_CLASS(LLPanelPickEdit);
-public:
-
- /**
- * Creates new panel
- */
- static LLPanelPickEdit* create();
-
- /*virtual*/ ~LLPanelPickEdit();
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- virtual void setPickData(const LLPickData* pick_data);
-
- /*virtual*/ BOOL postBuild();
-
- /**
- * Sets "Save" button click callback
- */
- virtual void setSaveCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Cancel" button click callback
- */
- virtual void setCancelCallback(const commit_callback_t& cb);
-
- /**
- * Resets panel and all cantrols to unedited state
- */
- /*virtual*/ void resetDirty();
-
- /**
- * Returns true if any of Pick properties was changed by user.
- */
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
-protected:
-
- LLPanelPickEdit();
-
- /**
- * Sends Pick properties to server.
- */
- void sendUpdate();
-
- /**
- * Called when snapshot image changes.
- */
- void onSnapshotChanged();
-
- /**
- * Callback for Pick snapshot, name and description changed event.
- */
- void onPickChanged(LLUICtrl* ctrl);
-
- /*virtual*/ void resetData();
-
- /**
- * Enables/disables "Save" button
- */
- void enableSaveButton(bool enable);
-
- /**
- * Callback for "Set Location" button click
- */
- void onClickSetLocation();
-
- /**
- * Callback for "Save" button click
- */
- void onClickSave();
-
- std::string getLocationNotice();
-
-protected:
-
- bool mLocationChanged;
- bool mNeedData;
- bool mNewPick;
-
-private:
-
- void initTexturePickerMouseEvents();
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
-private:
-
- LLIconCtrl* text_icon;
-};
-
-#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
deleted file mode 100644
index 8294977f99..0000000000
--- a/indra/newview/llpanelpicks.cpp
+++ /dev/null
@@ -1,1484 +0,0 @@
-/**
- * @file llpanelpicks.cpp
- * @brief LLPanelPicks and related class implementations
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpicks.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llcommandhandler.h"
-#include "lldispatcher.h"
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfloaterworldmap.h"
-#include "llnotificationsutil.h"
-#include "llstartup.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
-#include "lltrans.h"
-#include "llviewergenericmessage.h" // send_generic_message
-#include "llmenugl.h"
-#include "llviewermenu.h"
-#include "llregistry.h"
-
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llpanelavatar.h"
-#include "llpanelprofile.h"
-#include "llpanelpick.h"
-#include "llpanelclassified.h"
-
-static const std::string XML_BTN_NEW = "new_btn";
-static const std::string XML_BTN_DELETE = "trash_btn";
-static const std::string XML_BTN_INFO = "info_btn";
-static const std::string XML_BTN_TELEPORT = "teleport_btn";
-static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
-
-static const std::string PICK_ID("pick_id");
-static const std::string PICK_CREATOR_ID("pick_creator_id");
-static const std::string PICK_NAME("pick_name");
-
-static const std::string CLASSIFIED_ID("classified_id");
-static const std::string CLASSIFIED_NAME("classified_name");
-
-
-static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks");
-
-
-class LLPickHandler : public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
-
- std::set<LLUUID> mPickIds;
-
- // requires trusted browser to trigger
- LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
- {
- LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createPick();
- return true;
- }
-
- // then handle the general app/pick/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the pick_id
- LLUUID pick_id;
- if (!pick_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // edit the pick in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "edit")
- {
- mPickIds.insert(pick_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id);
- return true;
- }
- else
- {
- LL_WARNS() << "unknown verb " << verb << LL_ENDL;
- return false;
- }
- }
-
- void createPick()
- {
- // open the new pick panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewPick();
- }
- }
-
- void editPick(LLPickData* pick_info)
- {
- LLSD params;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_pick";
- params["pick_id"] = pick_info->pick_id;
- params["avatar_id"] = pick_info->creator_id;
- params["snapshot_id"] = pick_info->snapshot_id;
- params["pick_name"] = pick_info->name;
- params["pick_desc"] = pick_info->desc;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- // is this the pick that we asked for?
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end())
- {
- return;
- }
-
- // open the edit side tray for this pick
- if (pick_info->creator_id == gAgent.getID())
- {
- editPick(pick_info);
- }
- else
- {
- LL_WARNS() << "Can't edit a pick you did not create" << LL_ENDL;
- }
-
- // remove our observer now that we're done
- mPickIds.erase(pick_info->pick_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-};
-
-LLPickHandler gPickHandler;
-
-class LLClassifiedHandler :
- public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
- // throttle calls from untrusted browsers
- LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
-
- std::set<LLUUID> mClassifiedIds;
-
- std::string mRequestVerb;
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
- {
- LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createClassified();
- return true;
- }
-
- // then handle the general app/classified/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the classified
- LLUUID classified_id;
- if (!classified_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // show the classified in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "about")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
- else if (verb == "edit")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
-
- return false;
- }
-
- void createClassified()
- {
- // open the new classified panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewClassified();
- }
- }
-
- void openClassified(LLAvatarClassifiedInfo* c_info)
- {
- if (mRequestVerb == "about")
- {
- // open the classified info panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = c_info->creator_id;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "classified_details";
- params["classified_id"] = c_info->classified_id;
- params["classified_creator_id"] = c_info->creator_id;
- params["classified_snapshot_id"] = c_info->snapshot_id;
- params["classified_name"] = c_info->name;
- params["classified_desc"] = c_info->description;
- params["from_search"] = true;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
- else if (mRequestVerb == "edit")
- {
- if (c_info->creator_id == gAgent.getID())
- {
- LL_WARNS() << "edit in progress" << LL_ENDL;
- // open the new classified panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = gAgent.getID();
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_classified";
- params["classified_id"] = c_info->classified_id;
- LLFloaterSidePanelContainer::showPanel("my_profile", params);
- }
- else
- {
- LL_WARNS() << "Can't edit a classified you did not create" << LL_ENDL;
- }
- }
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- // is this the classified that we asked for?
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
- {
- return;
- }
-
- // open the detail side tray for this classified
- openClassified(c_info);
-
- // remove our observer now that we're done
- mClassifiedIds.erase(c_info->classified_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-
-};
-LLClassifiedHandler gClassifiedHandler;
-
-//////////////////////////////////////////////////////////////////////////
-
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPanelPicks::LLPanelPicks()
-: LLPanelProfileTab(),
- mPopupMenu(NULL),
- mProfilePanel(NULL),
- mPickPanel(NULL),
- mPicksList(NULL),
- mClassifiedsList(NULL),
- mPanelPickInfo(NULL),
- mPanelPickEdit(NULL),
- mPlusMenu(NULL),
- mPicksAccTab(NULL),
- mClassifiedsAccTab(NULL),
- mPanelClassifiedInfo(NULL),
- mNoClassifieds(false),
- mNoPicks(false)
-{
-}
-
-LLPanelPicks::~LLPanelPicks()
-{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
-}
-
-void* LLPanelPicks::create(void* data /* = NULL */)
-{
- return new LLPanelPicks();
-}
-
-void LLPanelPicks::updateData()
-{
- // Send Picks request only when we need to, not on every onOpen(during tab switch).
- if(isDirty())
- {
- mNoPicks = false;
- mNoClassifieds = false;
-
- mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
- mNoItemsLabel->setVisible(TRUE);
-
- mPicksList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
-
- mClassifiedsList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
- }
-}
-
-void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICKS == type)
- {
- LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
- if(avatar_picks && getAvatarId() == avatar_picks->target_id)
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(getAvatarId(), &av_name);
- getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
-
- // Save selection, to be able to edit same item after saving changes. See EXT-3023.
- LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
-
- mPicksList->clear();
-
- LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
- for(; avatar_picks->picks_list.end() != it; ++it)
- {
- LLUUID pick_id = it->first;
- std::string pick_name = it->second;
-
- LLPickItem* picture = LLPickItem::create();
- picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- picture->setPickName(pick_name);
- picture->setPickId(pick_id);
- picture->setCreatorId(getAvatarId());
-
- LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
- picture->update();
-
- LLSD pick_value = LLSD();
- pick_value.insert(PICK_ID, pick_id);
- pick_value.insert(PICK_NAME, pick_name);
- pick_value.insert(PICK_CREATOR_ID, getAvatarId());
-
- mPicksList->addItem(picture, pick_value);
-
- // Restore selection by item id.
- if ( pick_id == selected_id )
- mPicksList->selectItemByValue(pick_value);
-
- picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_picks", mPicksList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoPicks = !mPicksList->size();
- }
- else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
- {
- LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
- if(c_info && getAvatarId() == c_info->target_id)
- {
- // do not clear classified list in case we will receive two or more data packets.
- // list has been cleared in updateData(). (fix for EXT-6436)
-
- LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
- for(; c_info->classifieds_list.end() != it; ++it)
- {
- LLAvatarClassifieds::classified_data c_data = *it;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- c_item->setClassifiedName(c_data.name);
-
- LLSD pick_value = LLSD();
- pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
- pick_value.insert(CLASSIFIED_NAME, c_data.name);
-
- if (!findClassifiedById(c_data.classified_id))
- {
- mClassifiedsList->addItem(c_item, pick_value);
- }
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_classifieds", mClassifiedsList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoClassifieds = !mClassifiedsList->size();
- }
-
- updateNoItemsLabel();
-}
-
-LLPickItem* LLPanelPicks::getSelectedPickItem()
-{
- LLPanel* selected_item = mPicksList->getSelectedItem();
- if (!selected_item) return NULL;
-
- return dynamic_cast<LLPickItem*>(selected_item);
-}
-
-LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
-{
- LLPanel* selected_item = mClassifiedsList->getSelectedItem();
- if (!selected_item)
- {
- return NULL;
- }
- return dynamic_cast<LLClassifiedItem*>(selected_item);
-}
-
-BOOL LLPanelPicks::postBuild()
-{
- mPicksList = getChild<LLFlatListView>("picks_list");
- mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
-
- mPicksList->setCommitOnSelectionChange(true);
- mClassifiedsList->setCommitOnSelectionChange(true);
-
- mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
- mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
-
- mPicksList->setNoItemsCommentText(getString("no_picks"));
- mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
-
- mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
-
- childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
- childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
- childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
- childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
- childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
-
- mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
- mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
- mPicksAccTab->setDisplayChildren(true);
-
- mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
- mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
- mClassifiedsAccTab->setDisplayChildren(false);
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
- registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
- registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
- registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
- registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
- registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
- enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
- plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
- mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- return TRUE;
-}
-
-void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
-{
- std::string value = param.asString();
-
- if("new_pick" == value)
- {
- createNewPick();
- }
- else if("new_classified" == value)
- {
- createNewClassified();
- }
-}
-
-bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
-{
- std::string command_name = userdata.asString();
-
- if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
- {
- return false;
- }
-
- return true;
-}
-
-bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item)
-{
- if(c_item)
- {
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(panel)
- {
- return !panel->isNewWithErrors();
- }
-
- // we've got this classified from server - it's published
- return true;
- }
- return false;
-}
-
-void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
-{
- if(!mPicksAccTab->getDisplayChildren())
- {
- mPicksList->resetSelection(true);
- }
- if(!mClassifiedsAccTab->getDisplayChildren())
- {
- mClassifiedsList->resetSelection(true);
- }
-
- updateButtons();
-}
-
-void LLPanelPicks::onOpen(const LLSD& key)
-{
- const LLUUID id(key.asUUID());
- BOOL self = (gAgent.getID() == id);
-
- // only agent can edit her picks
- getChildView("edit_panel")->setEnabled(self);
- getChildView("edit_panel")->setVisible( self);
-
- // Disable buttons when viewing profile for first time
- if(getAvatarId() != id)
- {
- getChildView(XML_BTN_INFO)->setEnabled(FALSE);
- getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
- }
-
- // and see a special title - set as invisible by default in xml file
- if (self)
- {
- getChildView("pick_title")->setVisible( !self);
- getChildView("pick_title_agent")->setVisible( self);
-
- mPopupMenu->setItemVisible("pick_delete", TRUE);
- mPopupMenu->setItemVisible("pick_edit", TRUE);
- mPopupMenu->setItemVisible("pick_separator", TRUE);
- }
-
- if(getAvatarId() != id)
- {
- showAccordion("tab_picks", false);
- showAccordion("tab_classifieds", false);
-
- mPicksList->goToTop();
- // Set dummy value to make panel dirty and make it reload picks
- setValue(LLSD());
- }
-
- LLPanelProfileTab::onOpen(key);
-}
-
-void LLPanelPicks::onClosePanel()
-{
- if (mPanelClassifiedInfo)
- {
- onPanelClassifiedClose(mPanelClassifiedInfo);
- }
- if (mPanelPickInfo)
- {
- onPanelPickClose(mPanelPickInfo);
- }
-}
-
-void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
-{
- // Make sure only one of the lists has selection.
- if(f_list == mPicksList)
- {
- mClassifiedsList->resetSelection(true);
- }
- else if(f_list == mClassifiedsList)
- {
- mPicksList->resetSelection(true);
- }
- else
- {
- LL_WARNS() << "Unknown list" << LL_ENDL;
- }
-
- updateButtons();
-}
-
-//static
-void LLPanelPicks::onClickDelete()
-{
- LLSD value = mPicksList->getSelectedValue();
- if (value.isDefined())
- {
- LLSD args;
- args["PICK"] = value[PICK_NAME];
- LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));
- return;
- }
-
- value = mClassifiedsList->getSelectedValue();
- if(value.isDefined())
- {
- LLSD args;
- args["NAME"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));
- return;
- }
-}
-
-bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD pick_value = mPicksList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
- mPicksList->removeItemByValue(pick_value);
-
- mNoPicks = !mPicksList->size();
- if (mNoPicks)
- {
- showAccordion("tab_picks", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD value = mClassifiedsList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
- mClassifiedsList->removeItemByValue(value);
-
- mNoClassifieds = !mClassifiedsList->size();
- if (mNoClassifieds)
- {
- showAccordion("tab_classifieds", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (0 == option)
- {
- onClickTeleport();
- }
- return false;
-}
-
-//static
-void LLPanelPicks::onClickTeleport()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if(pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- pos = c_item->getPosGlobal();
- LLPanelClassifiedInfo::sendClickMessage("teleport", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- }
-
- if (!pos.isExactlyZero())
- {
- gAgent.teleportViaLocation(pos);
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- }
-}
-
-//static
-void LLPanelPicks::onClickMap()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if (pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- LLPanelClassifiedInfo::sendClickMessage("map", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- pos = c_item->getPosGlobal();
- }
-
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-
-void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
-{
- updateButtons();
-
- if (mPopupMenu)
- {
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- ((LLContextMenu*)mPopupMenu)->show(x, y);
- LLMenuGL::showPopup(item, mPopupMenu, x, y);
- }
-}
-
-void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
-{
- LLSD pick_value = mPicksList->getSelectedValue();
- if (pick_value.isUndefined()) return;
-
- LLSD args;
- args["PICK"] = pick_value[PICK_NAME];
- LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
-{
- LLSD value = mClassifiedsList->getSelectedValue();
- if (value.isUndefined()) return;
-
- LLSD args;
- args["CLASSIFIED"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::updateButtons()
-{
- bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
-
- if (getAvatarId() == gAgentID)
- {
- getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
- }
-
- getChildView(XML_BTN_INFO)->setEnabled(has_selected);
- getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item)
- {
- getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
- }
-}
-
-void LLPanelPicks::updateNoItemsLabel()
-{
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if (getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
-}
-
-void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
-{
- mProfilePanel = profile_panel;
-}
-
-
-void LLPanelPicks::buildPickPanel()
-{
-// if (mPickPanel == NULL)
-// {
-// mPickPanel = new LLPanelPick();
-// mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
-// }
-}
-
-void LLPanelPicks::onClickPlusBtn()
-{
- LLRect rect(getChildView(XML_BTN_NEW)->getRect());
-
- mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
- mPlusMenu->setButtonRect(rect, this);
- LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
-}
-
-void LLPanelPicks::createNewPick()
-{
- createPickEditPanel();
-
- getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
-}
-
-void LLPanelPicks::createNewClassified()
-{
- LLPanelClassifiedEdit* panel = NULL;
- createClassifiedEditPanel(&panel);
-
- getProfilePanel()->openPanel(panel, LLSD());
-}
-
-void LLPanelPicks::onClickInfo()
-{
- if(mPicksList->numSelected() > 0)
- {
- openPickInfo();
- }
- else if(mClassifiedsList->numSelected() > 0)
- {
- openClassifiedInfo();
- }
-}
-
-void LLPanelPicks::openPickInfo()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
-
- createPickInfoPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickInfo, params);
-}
-
-void LLPanelPicks::openClassifiedInfo()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["classified_snapshot_id"] = c_item->getSnapshotId();
- params["classified_name"] = c_item->getClassifiedName();
- params["classified_desc"] = c_item->getDescription();
- params["from_search"] = false;
-
- openClassifiedInfo(params);
-}
-
-void LLPanelPicks::openClassifiedInfo(const LLSD &params)
-{
- createClassifiedInfoPanel();
- getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
-}
-
-void LLPanelPicks::openClassifiedEdit(const LLSD& params)
-{
- LLUUID classified_id = params["classified_id"].asUUID();;
- LL_INFOS() << "opening classified " << classified_id << " for edit" << LL_ENDL;
- editClassified(classified_id);
-}
-
-void LLPanelPicks::showAccordion(const std::string& name, bool show)
-{
- LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
- tab->setVisible(show);
- LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
- acc->arrange();
-}
-
-void LLPanelPicks::onPanelPickClose(LLPanel* panel)
-{
- getProfilePanel()->closePanel(panel);
-}
-
-void LLPanelPicks::onPanelPickSave(LLPanel* panel)
-{
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
-{
- if(!panel->canClose())
- {
- return;
- }
-
- if(panel->isNew())
- {
- mEditClassifiedPanels[panel->getClassifiedId()] = panel;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
- c_item->fillIn(panel);
-
- LLSD c_value;
- c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
- c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
- mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
-
- // order does matter, showAccordion will invoke arrange for accordions.
- mClassifiedsAccTab->changeOpenClose(false);
- showAccordion("tab_classifieds", true);
- }
- else if(panel->isNewWithErrors())
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (c_item)
- {
- c_item->fillIn(panel);
- }
- }
- else
- {
- onPanelClassifiedClose(panel);
- return;
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
-{
- if(panel->getInfoLoaded() && !panel->isDirty())
- {
- std::vector<LLSD> values;
- mClassifiedsList->getValues(values);
- for(size_t n = 0; n < values.size(); ++n)
- {
- LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
- if(panel->getClassifiedId() == c_id)
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
- mClassifiedsList->getItemByValue(values[n]));
- llassert(c_item);
- if (c_item)
- {
- c_item->setClassifiedName(panel->getClassifiedName());
- c_item->setDescription(panel->getDescription());
- c_item->setSnapshotId(panel->getSnapshotId());
- }
- }
- }
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::createPickInfoPanel()
-{
- if(!mPanelPickInfo)
- {
- mPanelPickInfo = LLPanelPickInfo::create();
- mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
- mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
- mPanelPickInfo->setVisible(FALSE);
- }
-}
-
-void LLPanelPicks::createClassifiedInfoPanel()
-{
- mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
- mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
- mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
- mPanelClassifiedInfo->setVisible(FALSE);
-}
-
-void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
-{
- if(panel)
- {
- LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
- new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel));
- new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setVisible(FALSE);
- *panel = new_panel;
- }
-}
-
-void LLPanelPicks::createPickEditPanel()
-{
- mPanelPickEdit = LLPanelPickEdit::create();
- mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
- mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setVisible(FALSE);
-}
-
-// void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
-// {
-// if(!pick)
-// {
-// return;
-// }
-// }
-
-// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
-// {
-// if(!mPanelPickInfo)
-// {
-// mPanelPickInfo = LLPanelPickInfo::create();
-// mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
-// mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
-// mPanelPickInfo->setVisible(FALSE);
-// }
-//
-// LLSD params;
-// params["pick_id"] = pick->getPickId();
-// params["avatar_id"] = pick->getCreatorId();
-// params["snapshot_id"] = pick->getSnapshotId();
-// params["pick_name"] = pick->getPickName();
-// params["pick_desc"] = pick->getPickDesc();
-//
-// getProfilePanel()->openPanel(mPanelPickInfo, params);
-// }
-
-void LLPanelPicks::openPickEdit(const LLSD& params)
-{
- createPickEditPanel();
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelPickEdit()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
-
- createPickEditPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelClassifiedEdit()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined())
- {
- return;
- }
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (!c_item)
- {
- return;
- }
- editClassified(c_item->getClassifiedId());
-}
-
-LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id)
-{
- // HACK - find item by classified id. Should be a better way.
- std::vector<LLPanel*> items;
- mClassifiedsList->getItems(items);
- LLClassifiedItem* c_item = NULL;
- for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
- {
- LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it);
- if (test_item && test_item->getClassifiedId() == classified_id)
- {
- c_item = test_item;
- break;
- }
- }
- return c_item;
-}
-
-void LLPanelPicks::editClassified(const LLUUID& classified_id)
-{
- LLClassifiedItem* c_item = findClassifiedById(classified_id);
- if (!c_item)
- {
- LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL;
- return;
- }
-
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["snapshot_id"] = c_item->getSnapshotId();
- params["name"] = c_item->getClassifiedName();
- params["desc"] = c_item->getDescription();
- params["category"] = (S32)c_item->getCategory();
- params["content_type"] = (S32)c_item->getContentType();
- params["auto_renew"] = c_item->getAutoRenew();
- params["price_for_listing"] = c_item->getPriceForListing();
- params["location_text"] = c_item->getLocationText();
-
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(!panel)
- {
- createClassifiedEditPanel(&panel);
- mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
- }
- getProfilePanel()->openPanel(panel, params);
- panel->setPosGlobal(c_item->getPosGlobal());
-}
-
-void LLPanelPicks::onClickMenuEdit()
-{
- if(getSelectedPickItem())
- {
- onPanelPickEdit();
- }
- else if(getSelectedClassifiedItem())
- {
- onPanelClassifiedEdit();
- }
-}
-
-bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data)
-{
- std::string param = user_data.asString();
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item && "info" == param)
- {
- // dont show Info panel if classified was not created
- return isClassifiedPublished(c_item);
- }
-
- return true;
-}
-
-inline LLPanelProfile* LLPanelPicks::getProfilePanel()
-{
- llassert_always(NULL != mProfilePanel);
- return mProfilePanel;
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPickItem::LLPickItem()
-: LLPanel()
-, mPickID(LLUUID::null)
-, mCreatorID(LLUUID::null)
-, mParcelID(LLUUID::null)
-, mSnapshotID(LLUUID::null)
-, mNeedData(true)
-{
- buildFromFile("panel_pick_list_item.xml");
-}
-
-LLPickItem::~LLPickItem()
-{
- if (mCreatorID.notNull())
- {
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
- }
-
-}
-
-LLPickItem* LLPickItem::create()
-{
- return new LLPickItem();
-}
-
-void LLPickItem::init(LLPickData* pick_data)
-{
- setPickDesc(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- mPosGlobal = pick_data->pos_global;
- mSimName = pick_data->sim_name;
- mPickDescription = pick_data->desc;
- mUserName = pick_data->user_name;
- mOriginalName = pick_data->original_name;
-
- LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
- picture->setImageAssetID(pick_data->snapshot_id);
-}
-
-void LLPickItem::setPickName(const std::string& name)
-{
- mPickName = name;
- getChild<LLUICtrl>("picture_name")->setValue(name);
-
-}
-
-const std::string& LLPickItem::getPickName()
-{
- return mPickName;
-}
-
-const LLUUID& LLPickItem::getCreatorId()
-{
- return mCreatorID;
-}
-
-const LLUUID& LLPickItem::getSnapshotId()
-{
- return mSnapshotID;
-}
-
-void LLPickItem::setPickDesc(const std::string& descr)
-{
- getChild<LLUICtrl>("picture_descr")->setValue(descr);
-}
-
-void LLPickItem::setPickId(const LLUUID& id)
-{
- mPickID = id;
-}
-
-const LLUUID& LLPickItem::getPickId()
-{
- return mPickID;
-}
-
-const LLVector3d& LLPickItem::getPosGlobal()
-{
- return mPosGlobal;
-}
-
-const std::string LLPickItem::getDescription()
-{
- return getChild<LLUICtrl>("picture_descr")->getValue().asString();
-}
-
-void LLPickItem::update()
-{
- setNeedData(true);
- LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
-}
-
-void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
-{
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- LLPickData* pick_data = static_cast<LLPickData *>(data);
- if (!pick_data || mPickID != pick_data->pick_id)
- {
- return;
- }
-
- init(pick_data);
- setNeedData(false);
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
-}
-
-void set_child_visible(LLView* parent, const std::string& child_name, bool visible)
-{
- parent->getChildView(child_name)->setVisible(visible);
-}
-
-BOOL LLPickItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLPickItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
- : LLPanel()
- , mAvatarId(avatar_id)
- , mClassifiedId(classified_id)
-{
- buildFromFile("panel_classifieds_list_item.xml");
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
-}
-
-LLClassifiedItem::~LLClassifiedItem()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if( !c_info || c_info->classified_id != getClassifiedId() )
- {
- return;
- }
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setPosGlobal(c_info->pos_global);
-
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-BOOL LLClassifiedItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLClassifiedItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
-{
- if(!panel)
- {
- return;
- }
-
- setClassifiedName(panel->getClassifiedName());
- setDescription(panel->getDescription());
- setSnapshotId(panel->getSnapshotId());
- setCategory(panel->getCategory());
- setContentType(panel->getContentType());
- setAutoRenew(panel->getAutoRenew());
- setPriceForListing(panel->getPriceForListing());
- setPosGlobal(panel->getPosGlobal());
- setLocationText(panel->getClassifiedLocation());
-}
-
-void LLClassifiedItem::setClassifiedName(const std::string& name)
-{
- getChild<LLUICtrl>("name")->setValue(name);
-}
-
-void LLClassifiedItem::setDescription(const std::string& desc)
-{
- getChild<LLUICtrl>("description")->setValue(desc);
-}
-
-void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
-{
- getChild<LLUICtrl>("picture")->setValue(snapshot_id);
-}
-
-LLUUID LLClassifiedItem::getSnapshotId()
-{
- return getChild<LLUICtrl>("picture")->getValue();
-}
-
-//EOF
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
deleted file mode 100644
index fd7688b99d..0000000000
--- a/indra/newview/llpanelpicks.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * @file llpanelpicks.h
- * @brief LLPanelPicks and related class definitions
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLPANELPICKS_H
-#define LL_LLPANELPICKS_H
-
-#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llpanelavatar.h"
-#include "llregistry.h"
-
-class LLAccordionCtrlTab;
-class LLPanelProfile;
-class LLMessageSystem;
-class LLVector3d;
-class LLPanelProfileTab;
-class LLAgent;
-class LLMenuGL;
-class LLPickItem;
-class LLClassifiedItem;
-class LLFlatListView;
-class LLPanelPickInfo;
-class LLPanelPickEdit;
-class LLToggleableMenu;
-class LLPanelClassifiedInfo;
-class LLPanelClassifiedEdit;
-
-// *TODO
-// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
-// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
-
-class LLPanelPicks
- : public LLPanelProfileTab
-{
-public:
- LLPanelPicks();
- ~LLPanelPicks();
-
- static void* create(void* data);
-
- /*virtual*/ BOOL postBuild(void);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void onClosePanel();
-
- void processProperties(void* data, EAvatarProcessorType type);
-
- void updateData();
-
- // returns the selected pick item
- LLPickItem* getSelectedPickItem();
- LLClassifiedItem* getSelectedClassifiedItem();
- LLClassifiedItem* findClassifiedById(const LLUUID& classified_id);
-
- //*NOTE top down approch when panel toggling is done only by
- // parent panels failed to work (picks related code was in my profile panel)
- void setProfilePanel(LLPanelProfile* profile_panel);
-
- void createNewPick();
- void createNewClassified();
-
-protected:
- /*virtual*/void updateButtons();
- void updateNoItemsLabel();
-
-private:
- void onClickDelete();
- void onClickTeleport();
- void onClickMap();
-
- void onPlusMenuItemClicked(const LLSD& param);
- bool isActionEnabled(const LLSD& userdata) const;
-
- bool isClassifiedPublished(LLClassifiedItem* c_item);
-
- void onListCommit(const LLFlatListView* f_list);
- void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
-
- //------------------------------------------------
- // Callbacks which require panel toggling
- //------------------------------------------------
- void onClickPlusBtn();
- void onClickInfo();
- void onPanelPickClose(LLPanel* panel);
- void onPanelPickSave(LLPanel* panel);
- void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
- void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
- void openPickEdit(const LLSD& params);
- void onPanelPickEdit();
- void onPanelClassifiedEdit();
- void editClassified(const LLUUID& classified_id);
- void onClickMenuEdit();
-
- bool onEnableMenuItem(const LLSD& user_data);
-
- void openPickInfo();
- void openClassifiedInfo();
- void openClassifiedInfo(const LLSD& params);
- void openClassifiedEdit(const LLSD& params);
- friend class LLPanelProfile;
-
- void showAccordion(const std::string& name, bool show);
-
- void buildPickPanel();
-
- bool callbackDeletePick(const LLSD& notification, const LLSD& response);
- bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
- bool callbackTeleport(const LLSD& notification, const LLSD& response);
-
-
- virtual void onDoubleClickPickItem(LLUICtrl* item);
- virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
- virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
-
- LLPanelProfile* getProfilePanel();
-
- void createPickInfoPanel();
- void createPickEditPanel();
- void createClassifiedInfoPanel();
- void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
-
- LLMenuGL* mPopupMenu;
- LLPanelProfile* mProfilePanel;
- LLPanelPickInfo* mPickPanel;
- LLFlatListView* mPicksList;
- LLFlatListView* mClassifiedsList;
- LLPanelPickInfo* mPanelPickInfo;
- LLPanelClassifiedInfo* mPanelClassifiedInfo;
- LLPanelPickEdit* mPanelPickEdit;
- LLToggleableMenu* mPlusMenu;
- LLUICtrl* mNoItemsLabel;
-
- // <classified_id, edit_panel>
- typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
-
- // This map is needed for newly created classifieds. The purpose of panel is to
- // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
- panel_classified_edit_map_t mEditClassifiedPanels;
-
- LLAccordionCtrlTab* mPicksAccTab;
- LLAccordionCtrlTab* mClassifiedsAccTab;
-
- //true if picks list is empty after processing picks
- bool mNoPicks;
- //true if classifieds list is empty after processing classifieds
- bool mNoClassifieds;
-};
-
-class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLPickItem();
-
- static LLPickItem* create();
-
- void init(LLPickData* pick_data);
-
- void setPickName(const std::string& name);
-
- void setPickDesc(const std::string& descr);
-
- void setPickId(const LLUUID& id);
-
- void setCreatorId(const LLUUID& id) {mCreatorID = id;};
-
- void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
-
- void setNeedData(bool need){mNeedData = need;};
-
- const LLUUID& getPickId();
-
- const std::string& getPickName();
-
- const LLUUID& getCreatorId();
-
- const LLUUID& getSnapshotId();
-
- const LLVector3d& getPosGlobal();
-
- const std::string getDescription();
-
- const std::string& getSimName() { return mSimName; }
-
- const std::string& getUserName() { return mUserName; }
-
- const std::string& getOriginalName() { return mOriginalName; }
-
- const std::string& getPickDesc() { return mPickDescription; }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- void update();
-
- ~LLPickItem();
-
- /*virtual*/ BOOL postBuild();
-
- /** setting on/off background icon to indicate selected state */
- /*virtual*/ void setValue(const LLSD& value);
-
-protected:
-
- LLUUID mPickID;
- LLUUID mCreatorID;
- LLUUID mParcelID;
- LLUUID mSnapshotID;
- LLVector3d mPosGlobal;
- bool mNeedData;
-
- std::string mPickName;
- std::string mUserName;
- std::string mOriginalName;
- std::string mPickDescription;
- std::string mSimName;
-};
-
-class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
-
- virtual ~LLClassifiedItem();
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setValue(const LLSD& value);
-
- void fillIn(LLPanelClassifiedEdit* panel);
-
- LLUUID getAvatarId() {return mAvatarId;}
-
- void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
-
- LLUUID getClassifiedId() {return mClassifiedId;}
-
- void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
-
- void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
-
- const LLVector3d getPosGlobal() { return mPosGlobal; }
-
- void setLocationText(const std::string location) { mLocationText = location; }
-
- std::string getLocationText() { return mLocationText; }
-
- void setClassifiedName (const std::string& name);
-
- std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); }
-
- void setDescription(const std::string& desc);
-
- std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); }
-
- void setSnapshotId(const LLUUID& snapshot_id);
-
- LLUUID getSnapshotId();
-
- void setCategory(U32 cat) { mCategory = cat; }
-
- U32 getCategory() { return mCategory; }
-
- void setContentType(U32 ct) { mContentType = ct; }
-
- U32 getContentType() { return mContentType; }
-
- void setAutoRenew(U32 renew) { mAutoRenew = renew; }
-
- bool getAutoRenew() { return mAutoRenew; }
-
- void setPriceForListing(S32 price) { mPriceForListing = price; }
-
- S32 getPriceForListing() { return mPriceForListing; }
-
-private:
- LLUUID mAvatarId;
- LLUUID mClassifiedId;
- LLVector3d mPosGlobal;
- std::string mLocationText;
- U32 mCategory;
- U32 mContentType;
- bool mAutoRenew;
- S32 mPriceForListing;
-};
-
-#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9157df789f..fb5957ff8f 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelplaceinfo.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
#include "llavatarname.h"
#include "llsdutil.h"
@@ -42,7 +44,6 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
-#include "llpanelpick.h"
#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
@@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
-void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
+void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
{
LLPickData data;
data.pos_global = pos_global;
@@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
- pick_panel->setPickData(&data);
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
// static
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8bf67cfe7d..533215016a 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -38,7 +38,6 @@ class LLAvatarName;
class LLExpandableTextBox;
class LLIconCtrl;
class LLInventoryItem;
-class LLPanelPickEdit;
class LLParcel;
class LLScrollContainer;
class LLTextBox;
@@ -94,7 +93,7 @@ public:
// Create a pick for the location specified
// by global_pos.
- void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);
+ void createPick(const LLVector3d& pos_global);
protected:
static void onNameCache(LLTextBox* text, const std::string& full_name);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 69f181e1b3..74ec576554 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -63,7 +63,6 @@
#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
-#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
@@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()
mFilterEditor(NULL),
mPlaceProfile(NULL),
mLandmarkInfo(NULL),
- mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
}
else if (item == "pick")
{
- if (mPickPanel == NULL)
- {
- mPickPanel = LLPanelPickEdit::create();
- addChild(mPickPanel);
-
- mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
-
- togglePickPanel(TRUE);
- mPickPanel->onOpen(LLSD());
-
LLPanelPlaceInfo* panel = getCurrentInfoPanel();
if (panel)
{
- panel->createPick(mPosGlobal, mPickPanel);
+ panel->createPick(mPosGlobal);
}
-
- LLRect rect = getRect();
- mPickPanel->reshape(rect.getWidth(), rect.getHeight());
- mPickPanel->setRect(rect);
}
else if (item == "add_to_favbar")
{
@@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
return false;
}
-void LLPanelPlaces::togglePickPanel(BOOL visible)
-{
- if (mPickPanel)
- {
- mPickPanel->setVisible(visible);
- mPlaceProfile->setVisible(!visible);
- updateVerbs();
- }
-
-}
-
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceProfile || !mLandmarkInfo)
@@ -1309,15 +1279,11 @@ void LLPanelPlaces::updateVerbs()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
- bool is_pick_panel_visible = false;
- if(mPickPanel)
- {
- is_pick_panel_visible = mPickPanel->isInVisibleChain();
- }
+
bool have_3d_pos = ! mPosGlobal.isExactlyZero();
- mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
+ mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 3b87eb6cb9..e554099343 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -38,7 +38,6 @@ class LLLandmark;
class LLPanelLandmarkInfo;
class LLPanelPlaceProfile;
-class LLPanelPickEdit;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@@ -95,7 +94,6 @@ private:
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
bool onOverflowMenuItemEnable(const LLSD& param);
- void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
void onGearMenuClick();
void onSortingMenuClick();
@@ -103,9 +101,6 @@ private:
void onRemoveButtonClicked();
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
- void toggleMediaPanel();
- void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
@@ -122,7 +117,6 @@ private:
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
- LLPanelPickEdit* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 5f13b223fb..f4eaa78f11 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.cpp
* @brief Profile panel implementation
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, Linden Research, Inc.
+*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
-*
+*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
-*
+*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
+*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -27,32 +27,433 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelprofile.h"
-#include "llagent.h"
+// Common
+#include "llavatarnamecache.h"
+#include "llsdutil.h"
+#include "llslurl.h"
+#include "lldateutil.h" //ageFromDate
+
+// UI
+#include "llavatariconctrl.h"
+#include "llclipboard.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llloadingindicator.h"
+#include "llmenubutton.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
+#include "llgrouplist.h"
+#include "llurlaction.h"
+
+// Image
+#include "llimagej2c.h"
+
+// Newview
+#include "llagent.h" //gAgent
+#include "llagentpicksinfo.h"
#include "llavataractions.h"
-#include "llfloaterreg.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llpanelpicks.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llviewernetwork.h"
+#include "llfloaterprofiletexture.h"
+#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
+#include "llfilepicker.h"
+#include "llfirstuse.h"
+#include "llgroupactions.h"
+#include "lllogchat.h"
#include "llmutelist.h"
+#include "llnotificationsutil.h"
#include "llpanelblockedlist.h"
+#include "llpanelprofileclassifieds.h"
+#include "llpanelprofilepicks.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h" //is_agent_mappable
+#include "llviewermenufile.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
#include "llweb.h"
-static const std::string PANEL_PICKS = "panel_picks";
-std::string getProfileURL(const std::string& agent_name)
+static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife");
+static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web");
+static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife");
+static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes");
+static LLPanelInjector<LLPanelProfile> t_panel_profile("panel_profile");
+
+static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife";
+static const std::string PANEL_WEB = "panel_profile_web";
+static const std::string PANEL_PICKS = "panel_profile_picks";
+static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds";
+static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife";
+static const std::string PANEL_NOTES = "panel_profile_notes";
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile";
+static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
+
+
+//////////////////////////////////////////////////////////////////////////
+
+void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
{
- std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
- LLSD subs;
- subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
- subs["AGENT_NAME"] = agent_name;
- url = LLWeb::expandURLSubstitutions(url, subs);
- LLStringUtil::toLower(url);
- return url;
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id));
+ if (!floater_profile)
+ {
+ // floater is dead, so panels are dead as well
+ return;
+ }
+
+ LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE);
+ LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel);
+ if (!panel_profile)
+ {
+ LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL;
+ return;
+ }
+
+
+ // Avatar Data
+
+ LLAvatarData *avatar_data = &panel_profile->mAvatarData;
+ std::string birth_date;
+
+ avatar_data->agent_id = agent_id;
+ avatar_data->avatar_id = agent_id;
+ avatar_data->image_id = result["sl_image_id"].asUUID();
+ avatar_data->fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data->partner_id = result["partner_id"].asUUID();
+ avatar_data->about_text = result["sl_about_text"].asString();
+ avatar_data->fl_about_text = result["fl_about_text"].asString();
+ avatar_data->born_on = result["member_since"].asDate();
+ avatar_data->profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data->flags = 0;
+
+ if (result["online"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ONLINE;
+ }
+ if (result["allow_publish"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ALLOW_PUBLISH;
+ }
+ if (result["identified"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_IDENTIFIED;
+ }
+ if (result["transacted"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_TRANSACTED;
+ }
+
+ avatar_data->caption_index = 0;
+ if (result.has("charter_member")) // won't be present if "caption" is set
+ {
+ avatar_data->caption_index = result["charter_member"].asInteger();
+ }
+ else if (result.has("caption"))
+ {
+ avatar_data->caption_text = result["caption"].asString();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE);
+ LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel);
+ if (panel_sl)
+ {
+ panel_sl->processProfileProperties(avatar_data);
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE);
+ LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel);
+ if (panel_web)
+ {
+ panel_web->setLoaded();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE);
+ LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel);
+ if (panel_first)
+ {
+ panel_first->processProperties(avatar_data);
+ }
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE);
+ LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel);
+ if (panel_picks)
+ {
+ // Refresh pick limit before processing
+ LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks);
+ panel_picks->processProperties(&avatar_picks);
+ }
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ if (panel_sl)
+ {
+ panel_sl->processGroupProperties(&avatar_groups);
+ }
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE);
+ LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel);
+ if (panel_notes)
+ {
+ panel_notes->processProperties(&avatar_notes);
+ }
+}
+
+//TODO: changes take two minutes to propagate!
+// Add some storage that holds updated data for two minutes
+// for new instances to reuse the data
+// Profile data is only relevant to won avatar, but notes
+// are for everybody
+void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+}
+
+LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ return LLUUID::null;
+ }
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Upload the image
+
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
+
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
+ uploaderhttpOpts->setFollowRedirects(true);
+
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_WARNS("AvatarProperties") << result << LL_ENDL;
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (result["state"].asString() != "complete")
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
+
+ return result["new_asset"].asUUID();
}
+enum EProfileImageType
+{
+ PROFILE_IMAGE_SL,
+ PROFILE_IMAGE_FL,
+};
+
+void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLSD data;
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ data["profile-image-asset"] = "sl_image_id";
+ break;
+ case PROFILE_IMAGE_FL:
+ data["profile-image-asset"] = "fl_image_id";
+ break;
+ }
+
+ LLUUID result = post_profile_image(cap_url, data, path_to_image, handle);
+
+ // reset loading indicator
+ if (!handle->isDead())
+ {
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ }
+ }
+
+ // Cleanup
+ LLFile::remove(path_to_image);
+ delete handle;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLProfileHandler
+
class LLProfileHandler : public LLCommandHandler
{
public:
@@ -73,6 +474,10 @@ public:
};
LLProfileHandler gProfileHandler;
+
+//////////////////////////////////////////////////////////////////////////
+// LLAgentHandler
+
class LLAgentHandler : public LLCommandHandler
{
public:
@@ -178,279 +583,2070 @@ public:
}
return true;
}
+
+ // reportAbuse is here due to convoluted avatar handling
+ // in LLScrollListCtrl and LLTextBase
+ if (verb == "reportAbuse" && web == NULL)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(avatar_id, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable");
+ }
+ return true;
+ }
return false;
}
};
LLAgentHandler gAgentHandler;
-//-- LLPanelProfile::ChildStack begins ----------------------------------------
-LLPanelProfile::ChildStack::ChildStack()
-: mParent(NULL)
+///----------------------------------------------------------------------------
+/// LLFloaterProfilePermissions
+///----------------------------------------------------------------------------
+
+class LLFloaterProfilePermissions
+ : public LLFloater
+ , public LLFriendObserver
{
+public:
+ LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id);
+ ~LLFloaterProfilePermissions();
+ BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
+ void draw() override;
+ void changed(U32 mask) override; // LLFriendObserver
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+ bool hasUnsavedChanges() { return mHasUnsavedPermChanges; }
+
+ void onApplyRights();
+
+private:
+ void fillRightsData();
+ void rightsConfirmationCallback(const LLSD& notification, const LLSD& response);
+ void confirmModifyRights(bool grant);
+ void onCommitSeeOnlineRights();
+ void onCommitEditRights();
+ void onCancel();
+
+ LLTextBase* mDescription;
+ LLCheckBoxCtrl* mOnlineStatus;
+ LLCheckBoxCtrl* mMapRights;
+ LLCheckBoxCtrl* mEditObjectRights;
+ LLButton* mOkBtn;
+ LLButton* mCancelBtn;
+
+ LLUUID mAvatarID;
+ F32 mContextConeOpacity;
+ bool mHasUnsavedPermChanges;
+ LLHandle<LLView> mOwnerHandle;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id)
+ : LLFloater(LLSD())
+ , mAvatarID(avatar_id)
+ , mContextConeOpacity(0.0f)
+ , mHasUnsavedPermChanges(false)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_permissions.xml");
}
-LLPanelProfile::ChildStack::~ChildStack()
+LLFloaterProfilePermissions::~LLFloaterProfilePermissions()
{
- while (mStack.size() != 0)
- {
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- if (viewp)
- {
- viewp->die();
- }
- }
- mStack.pop_back();
- }
+ mAvatarNameCacheConnection.disconnect();
+ if (mAvatarID.notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
+ }
}
-void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
+BOOL LLFloaterProfilePermissions::postBuild()
{
- llassert_always(parent != NULL);
- mParent = parent;
+ mDescription = getChild<LLTextBase>("perm_description");
+ mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check");
+ mMapRights = getChild<LLCheckBoxCtrl>("map_check");
+ mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check");
+ mOkBtn = getChild<LLButton>("perms_btn_ok");
+ mCancelBtn = getChild<LLButton>("perms_btn_cancel");
+
+ mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr);
+ mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr);
+ mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr);
+ mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr);
+ mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr);
+
+ return TRUE;
}
-/// Save current parent's child views and remove them from the child list.
-bool LLPanelProfile::ChildStack::push()
+void LLFloaterProfilePermissions::onOpen(const LLSD& key)
{
- view_list_t vlist = *mParent->getChildList();
+ if (LLAvatarActions::isFriend(mAvatarID))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
+ fillRightsData();
+ }
- for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->removeChild(viewp);
- }
+ mCancelBtn->setFocus(true);
- mStack.push_back(vlist);
- dump();
- return true;
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2));
}
-/// Restore saved children (adding them back to the child list).
-bool LLPanelProfile::ChildStack::pop()
+void LLFloaterProfilePermissions::draw()
{
- if (mStack.size() == 0)
- {
- LL_WARNS() << "Empty stack" << LL_ENDL;
- llassert(mStack.size() == 0);
- return false;
- }
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+ LLFloater::draw();
+}
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->addChild(viewp);
- }
+void LLFloaterProfilePermissions::changed(U32 mask)
+{
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
- mStack.pop_back();
- dump();
- return true;
+void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ LLStringUtil::format_map_t args;
+ args["[AGENT_NAME]"] = av_name.getDisplayName();
+ std::string descritpion = getString("description_string", args);
+ mDescription->setValue(descritpion);
}
-/// Temporarily add all saved children back.
-void LLPanelProfile::ChildStack::preParentReshape()
+void LLFloaterProfilePermissions::fillRightsData()
{
- mSavedStack = mStack;
- while(mStack.size() > 0)
- {
- pop();
- }
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+
+ BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE;
+ mOnlineStatus->setValue(see_online);
+ mMapRights->setEnabled(see_online);
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
}
-/// Add the temporarily saved children back.
-void LLPanelProfile::ChildStack::postParentReshape()
+void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification,
+ const LLSD& response)
{
- mStack = mSavedStack;
- mSavedStack = stack_t();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) // canceled
+ {
+ mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE);
+ }
+ else
+ {
+ mHasUnsavedPermChanges = true;
+ }
+}
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
- {
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- LLView* viewp = *list_it;
- LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL;
- mParent->removeChild(viewp);
- }
- }
+void LLFloaterProfilePermissions::confirmModifyRights(bool grant)
+{
+ LLSD args;
+ args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString();
+ LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(),
+ boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2));
}
-void LLPanelProfile::ChildStack::dump()
+void LLFloaterProfilePermissions::onCommitSeeOnlineRights()
{
- unsigned lvl = 0;
- LL_DEBUGS() << "child stack dump:" << LL_ENDL;
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
- {
- std::ostringstream dbg_line;
- dbg_line << "lvl #" << lvl << ":";
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- dbg_line << " " << (*list_it)->getName();
- }
- LL_DEBUGS() << dbg_line.str() << LL_ENDL;
- }
+ bool see_online = mOnlineStatus->getValue().asBoolean();
+ mMapRights->setEnabled(see_online);
+ if (see_online)
+ {
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mMapRights->setValue(FALSE);
+ }
+ mHasUnsavedPermChanges = true;
}
-//-- LLPanelProfile::ChildStack ends ------------------------------------------
+void LLFloaterProfilePermissions::onCommitEditRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
-LLPanelProfile::LLPanelProfile()
- : LLPanel()
- , mAvatarId(LLUUID::null)
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL;
+ closeFloater();
+ return;
+ }
+
+ bool allow_modify_objects = mEditObjectRights->getValue().asBoolean();
+
+ // if modify objects checkbox clicked
+ if (buddy_relationship->isRightGrantedTo(
+ LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
+ {
+ confirmModifyRights(allow_modify_objects);
+ }
+}
+
+void LLFloaterProfilePermissions::onApplyRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL;
+ return;
+ }
+
+ S32 rights = 0;
+
+ if (mOnlineStatus->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ }
+ if (mMapRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ }
+ if (mEditObjectRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
+ }
+
+ LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights);
+
+ closeFloater();
+}
+
+void LLFloaterProfilePermissions::onCancel()
{
- mChildStack.setParent(this);
+ closeFloater();
}
-BOOL LLPanelProfile::postBuild()
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileSecondLife
+
+LLPanelProfileSecondLife::LLPanelProfileSecondLife()
+ : LLPanelProfileTab()
+ , mAvatarNameCacheConnection()
+ , mHasUnsavedDescriptionChanges(false)
+ , mWaitingForImageUpload(false)
+ , mAllowPublish(false)
+{
+}
+
+LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
+{
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
+ }
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+BOOL LLPanelProfileSecondLife::postBuild()
+{
+ mGroupList = getChild<LLGroupList>("group_list");
+ mShowInSearchCombo = getChild<LLComboBox>("show_in_search");
+ mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic");
+ mSecondLifePicLayout = getChild<LLPanel>("image_panel");
+ mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit");
+ mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu");
+ mSaveDescriptionChanges = getChild<LLButton>("save_description_changes");
+ mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes");
+ mCanSeeOnlineIcon = getChild<LLIconCtrl>("can_see_online");
+ mCantSeeOnlineIcon = getChild<LLIconCtrl>("cant_see_online");
+ mCanSeeOnMapIcon = getChild<LLIconCtrl>("can_see_on_map");
+ mCantSeeOnMapIcon = getChild<LLIconCtrl>("cant_see_on_map");
+ mCanEditObjectsIcon = getChild<LLIconCtrl>("can_edit_objects");
+ mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects");
+
+ mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr);
+ mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileSecondLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ LLUUID avatar_id = getAvatarId();
+
+ BOOL own_profile = getSelfProfile();
+
+ mGroupList->setShowNone(!own_profile);
+
+ childSetVisible("notes_panel", !own_profile);
+ childSetVisible("settings_panel", own_profile);
+ childSetVisible("about_buttons_panel", own_profile);
+
+ if (own_profile)
+ {
+ // Group list control cannot toggle ForAgent loading
+ // Less than ideal, but viewing own profile via search is edge case
+ mGroupList->enableForAgent(false);
+ }
+
+ // Init menu, menu needs to be created in scope of a registar to work correctly.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit;
+ commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); });
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable;
+ enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); });
+ enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); });
+
+ if (own_profile)
+ {
+ mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+ else
+ {
+ // Todo: use PeopleContextMenu instead?
+ mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+
+ mDescriptionEdit->setParseHTML(!own_profile);
+
+ if (!own_profile)
+ {
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE);
+ updateOnlineStatus();
+ fillRightsData();
+ }
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+}
+
+void LLPanelProfileSecondLife::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ else
+ {
+ LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::refreshName()
+{
+ if (!mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+ }
+}
+
+void LLPanelProfileSecondLife::resetData()
+{
+ resetLoading();
+
+ // Set default image and 1:1 dimensions for it
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight());
+
+ setDescriptionText(LLStringUtil::null);
+ mGroups.clear();
+ mGroupList->setGroups(mGroups);
+
+ bool own_profile = getSelfProfile();
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(!own_profile);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(!own_profile);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(!own_profile);
+
+ mCanSeeOnlineIcon->setEnabled(false);
+ mCantSeeOnlineIcon->setEnabled(false);
+ mCanSeeOnMapIcon->setEnabled(false);
+ mCantSeeOnMapIcon->setEnabled(false);
+ mCanEditObjectsIcon->setEnabled(false);
+ mCantEditObjectsIcon->setEnabled(false);
+
+ childSetVisible("partner_layout", FALSE);
+}
+
+void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
+{
+ LLUUID avatar_id = getAvatarId();
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile())
+ {
+ // Relies onto friend observer to get information about online status updates.
+ // Once SL-17506 gets implemented, condition might need to become:
+ // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE)
+ processOnlineStatus(relationship != NULL,
+ gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS),
+ (avatar_data->flags & AVATAR_ONLINE));
+ }
+
+ fillCommonData(avatar_data);
+
+ fillPartnerData(avatar_data);
+
+ fillAccountStatus(avatar_data);
+
+ setLoaded();
+}
+
+void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups)
+{
+
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
+ const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
+
+ for (; it_end != it; ++it)
+ {
+ LLAvatarGroups::LLGroupData group_data = *it;
+ mGroups[group_data.group_name] = group_data.group_id;
+ }
+
+ mGroupList->setGroups(mGroups);
+}
+
+void LLPanelProfileSecondLife::openGroupProfile()
+{
+ LLUUID group_id = mGroupList->getSelectedUUID();
+ LLGroupActions::show(group_id);
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+ getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName());
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploading(bool loading)
+{
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ mWaitingForImageUpload = loading;
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mSecondLifePic->setValue(image_asset_id);
+ mImageId = image_asset_id;
+
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+
+ setProfileImageUploading(false);
+}
+
+bool LLPanelProfileSecondLife::hasUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ return true;
+ }
+ }
+ // if floater
+ return mHasUnsavedDescriptionChanges;
+}
+
+void LLPanelProfileSecondLife::commitUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ perm->onApplyRights();
+ }
+ }
+ if (mHasUnsavedDescriptionChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
+{
+ // Refresh avatar id in cache with new info to prevent re-requests
+ // and to make sure icons in text will be up to date
+ LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id);
+
+ fillAgeData(avatar_data->born_on);
+
+ setDescriptionText(avatar_data->about_text);
+
+ if (avatar_data->image_id.notNull())
+ {
+ mSecondLifePic->setValue(avatar_data->image_id);
+ mImageId = avatar_data->image_id;
+ }
+ else
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+ }
+
+ // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ if (getSelfProfile())
+ {
+ mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH;
+ mShowInSearchCombo->setValue((BOOL)mAllowPublish);
+ }
+}
+
+void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data)
+{
+ LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link");
+ if (avatar_data->partner_id.notNull())
+ {
+ childSetVisible("partner_layout", TRUE);
+ LLStringUtil::format_map_t args;
+ args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString();
+ std::string partner_text = getString("partner_text", args);
+ partner_text_ctrl->setText(partner_text);
+ }
+ else
+ {
+ childSetVisible("partner_layout", FALSE);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data)
+{
+ LLStringUtil::format_map_t args;
+ args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data);
+ args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data);
+
+ std::string caption_text = getString("CaptionTextAcctInfo", args);
+ getChild<LLUICtrl>("account_info")->setValue(caption_text);
+}
+
+void LLPanelProfileSecondLife::fillRightsData()
+{
+ if (getSelfProfile())
+ {
+ return;
+ }
+
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights;
+ bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights;
+ bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights;
+
+ mCanSeeOnlineIcon->setVisible(can_see_online);
+ mCantSeeOnlineIcon->setVisible(!can_see_online);
+ mCanSeeOnMapIcon->setVisible(can_see_on_map);
+ mCantSeeOnMapIcon->setVisible(!can_see_on_map);
+ mCanEditObjectsIcon->setVisible(can_edit_objects);
+ mCantEditObjectsIcon->setVisible(!can_edit_objects);
+
+ mCanSeeOnlineIcon->setEnabled(true);
+ mCantSeeOnlineIcon->setEnabled(true);
+ mCanSeeOnMapIcon->setEnabled(true);
+ mCantSeeOnMapIcon->setEnabled(true);
+ mCanEditObjectsIcon->setEnabled(true);
+ mCantEditObjectsIcon->setEnabled(true);
+ }
+ else
+ {
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(false);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(false);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(false);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
+{
+ std::string name_and_date = getString("date_format");
+ LLSD args_name;
+ args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
+ LLStringUtil::format(name_and_date, args_name);
+ getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date);
+
+ std::string register_date = getString("age_format");
+ LLSD args_age;
+ args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now());
+ LLStringUtil::format(register_date, args_age);
+ getChild<LLUICtrl>("user_age")->setValue(register_date);
+}
+
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep)
+{
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ if (!success || imagep->getFullWidth() == imagep->getFullHeight())
+ {
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth());
+ }
+ else
+ {
+ // assume 3:4, for sake of firestorm
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4);
+ }
+}
+
+//static
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ if (!userdata) return;
+
+ LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (panel)
+ {
+ panel->onImageLoaded(success, src_vi);
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
+
+// virtual, called by LLAvatarTracker
+void LLPanelProfileSecondLife::changed(U32 mask)
+{
+ updateOnlineStatus();
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
+
+// virtual, called by LLVoiceClient
+void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE);
+}
+
+void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ LLPanelProfileTab::setAvatarId(avatar_id);
+
+ if (LLAvatarActions::isFriend(getAvatarId()))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this);
+ }
+ }
+}
+
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
+void LLPanelProfileSecondLife::updateOnlineStatus()
+{
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if (relationship != NULL)
+ {
+ // For friend let check if he allowed me to see his status
+ bool online = relationship->isOnline();
+ bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
+ processOnlineStatus(true, perm_granted, online);
+ }
+ else
+ {
+ childSetVisible("frind_layout", false);
+ childSetVisible("online_layout", false);
+ childSetVisible("offline_layout", false);
+ }
+}
+
+void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online)
+{
+ childSetVisible("frind_layout", is_friend);
+ childSetVisible("online_layout", online && show_online);
+ childSetVisible("offline_layout", !online && show_online);
+}
+
+void LLPanelProfileSecondLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mShowInSearchCombo->setEnabled(TRUE);
+ mDescriptionEdit->setEnabled(TRUE);
+ }
+}
+
+
+
+class LLProfileImagePicker : public LLFilePickerThread
+{
+public:
+ LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);
+ ~LLProfileImagePicker();
+ void notify(const std::vector<std::string>& filenames) override;
+
+private:
+ LLHandle<LLPanel> *mHandle;
+ EProfileImageType mType;
+};
+
+LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)
+ : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE),
+ mHandle(handle),
+ mType(type)
+{
+}
+
+LLProfileImagePicker::~LLProfileImagePicker()
+{
+ delete mHandle;
+}
+
+void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
+{
+ if (mHandle->isDead())
+ {
+ return;
+ }
+ if (filenames.empty())
+ {
+ return;
+ }
+ std::string file_path = filenames[0];
+ if (file_path.empty())
+ {
+ return;
+ }
+
+ // generate a temp texture file for coroutine
+ std::string temp_file = gDirUtilp->getTempFilename();
+ U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
+ const S32 MAX_DIM = 256;
+ if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
+ {
+ //todo: image not supported notification
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ if (cap_url.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
+ return;
+ }
+
+ switch (mType)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ }
+
+ LLCoros::instance().launch("postAgentUserImageCoro",
+ boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle));
+
+ mHandle = nullptr; // transferred to post_profile_image_coro
+}
+
+void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ // todo: consider moving this into LLAvatarActions::onCommit(name, id)
+ // and making all other flaoters, like people menu do the same
+ if (item_name == "im")
+ {
+ LLAvatarActions::startIM(agent_id);
+ }
+ else if (item_name == "offer_teleport")
+ {
+ LLAvatarActions::offerTeleport(agent_id);
+ }
+ else if (item_name == "request_teleport")
+ {
+ LLAvatarActions::teleportRequest(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ LLAvatarActions::startCall(agent_id);
+ }
+ else if (item_name == "chat_history")
+ {
+ LLAvatarActions::viewChatHistory(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ LLAvatarActions::requestFriendshipDialog(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ LLAvatarActions::removeFriendDialog(agent_id);
+ }
+ else if (item_name == "invite_to_group")
+ {
+ LLAvatarActions::inviteToGroup(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ LLAvatarActions::showOnMap(agent_id);
+ }
+ else if (item_name == "share")
+ {
+ LLAvatarActions::share(agent_id);
+ }
+ else if (item_name == "pay")
+ {
+ LLAvatarActions::pay(agent_id);
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ LLAvatarActions::toggleBlock(agent_id);
+ }
+ else if (item_name == "copy_user_id")
+ {
+ LLWString wstr = utf8str_to_wstring(getAvatarId().asString());
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "agent_permissions")
+ {
+ onShowAgentPermissionsDialog();
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getAvatarId(), &av_name))
+ {
+ // shouldn't happen, option is supposed to be invisible while name is fetching
+ LL_WARNS() << "Failed to get agent data" << LL_ENDL;
+ return;
+ }
+ LLWString wstr;
+ if (item_name == "copy_display_name")
+ {
+ wstr = utf8str_to_wstring(av_name.getDisplayName(true));
+ }
+ else if (item_name == "copy_username")
+ {
+ wstr = utf8str_to_wstring(av_name.getUserName());
+ }
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "edit_display_name")
+ {
+ LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
+ LLFirstUse::setDisplayName(false);
+ }
+ else if (item_name == "edit_partner")
+ {
+ std::string url = "https://[GRID]/my/account/partners.php";
+ LLSD subs;
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLUrlAction::openURL(url);
+ }
+ else if (item_name == "upload_photo")
+ {
+ (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+ else if (item_name == "change_photo")
+ {
+ onShowTexturePicker();
+ }
+ else if (item_name == "remove_photo")
+ {
+ onCommitProfileImage(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+}
+
+bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "offer_teleport" || item_name == "request_teleport")
+ {
+ return LLAvatarActions::canOfferTeleport(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ return mVoiceStatus;
+ }
+ else if (item_name == "chat_history")
+ {
+ return LLLogChat::isTranscriptExist(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ return !LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id))
+ || gAgent.isGodlike();
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::canBlock(agent_id);
+ }
+ else if (item_name == "agent_permissions")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ return !mAvatarNameCacheConnection.connected();
+ }
+ else if (item_name == "upload_photo"
+ || item_name == "change_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+ else if (item_name == "remove_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+
+ return false;
+}
+
+bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::isBlocked(agent_id);
+ }
+ return false;
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS);
- panel_picks->setProfilePanel(this);
+ if (av_name.getDisplayName().empty())
+ {
+ // something is wrong, tell user to try again later
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ return;
+ }
- getTabContainer()[PANEL_PICKS] = panel_picks;
+ LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update "
+ << LLDate(av_name.mNextUpdate) << LL_ENDL;
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
- return TRUE;
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // if the update time is more than a year in the future, it means updates have been blocked
+ // show a more general message
+ static const S32 YEAR = 60*60*24*365;
+ if (now_secs + YEAR < av_name.mNextUpdate)
+ {
+ LLNotificationsUtil::add("SetDisplayNameBlocked");
+ return;
+ }
+ }
+
+ LLFloaterReg::showInstance("display_name");
+}
+
+void LLPanelProfileSecondLife::setDescriptionText(const std::string &text)
+{
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+
+ mDescriptionText = text;
+ mDescriptionEdit->setValue(mDescriptionText);
}
-// virtual
-void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
+void LLPanelProfileSecondLife::onSetDescriptionDirty()
{
- // Temporarily add saved children back and reshape them.
- mChildStack.preParentReshape();
- LLPanel::reshape(width, height, called_from_parent);
- mChildStack.postParentReshape();
+ mSaveDescriptionChanges->setEnabled(TRUE);
+ mDiscardDescriptionChanges->setEnabled(TRUE);
+ mHasUnsavedDescriptionChanges = true;
+}
+
+void LLPanelProfileSecondLife::onShowInSearchCallback()
+{
+ S32 value = mShowInSearchCombo->getValue().asInteger();
+ if (mAllowPublish == (bool)value)
+ {
+ return;
+ }
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ mAllowPublish = value;
+ LLSD data;
+ data["allow_publish"] = mAllowPublish;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileSecondLife::onSaveDescriptionChanges()
+{
+ mDescriptionText = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+}
+
+void LLPanelProfileSecondLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mDescriptionText);
+}
+
+void LLPanelProfileSecondLife::onShowAgentPermissionsDialog()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId());
+ mFloaterPermissionsHandle = perms->getHandle();
+ perms->openFloater();
+ perms->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterPermissionsHandle);
+ }
+ }
+ else // already open
+ {
+ floater->setMinimized(FALSE);
+ floater->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onShowAgentProfileTexture()
+{
+ if (!getIsLoaded())
+ {
+ return;
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater);
+ mFloaterProfileTextureHandle = texture_view->getHandle();
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ texture_view->openFloater();
+ texture_view->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterProfileTextureHandle);
+ }
+ }
+ else // already open
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ texture_view->setMinimized(FALSE);
+ texture_view->setVisibleAndFrontmost(TRUE);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::onShowTexturePicker()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitProfileImage(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["sl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId == LLUUID::null)
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ }
+ else
+ {
+ mSecondLifePic->setValue(mImageId);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId == LLUUID::null)
+ {
+ texture_view->resetAsset();
+ }
+ else
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileWeb
+
+LLPanelProfileWeb::LLPanelProfileWeb()
+ : LLPanelProfileTab()
+ , mWebBrowser(NULL)
+ , mAvatarNameCacheConnection()
+{
+}
+
+LLPanelProfileWeb::~LLPanelProfileWeb()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+void LLPanelProfileWeb::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLPanelProfileWeb::postBuild()
+{
+ mWebBrowser = getChild<LLMediaCtrl>("profile_html");
+ mWebBrowser->addObserver(this);
+ mWebBrowser->setHomePageUrl("about:blank");
+
+ return TRUE;
+}
+
+void LLPanelProfileWeb::resetData()
+{
+ mWebBrowser->navigateHome();
+}
+
+void LLPanelProfileWeb::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty())
+ {
+ setIsLoading();
+
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ std::string username = av_name.getAccountName();
+ if (username.empty())
+ {
+ username = LLCacheName::buildUsername(av_name.getDisplayName());
+ }
+ else
+ {
+ LLStringUtil::replaceChar(username, ' ', '.');
+ }
+
+ mURLWebProfile = getProfileURL(username, true);
+ if (mURLWebProfile.empty())
+ {
+ return;
+ }
+
+ //if the tab was opened before name was resolved, load the panel now
+ updateData();
+}
+
+void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl)
+{
+ if (!mURLHome.empty())
+ {
+ LLSD::String valstr = ctrl->getValue().asString();
+ if (valstr.empty())
+ {
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML );
+ }
+ else if (valstr == "popout")
+ {
+ // open in viewer's browser, new window
+ LLWeb::loadURLInternal(mURLHome);
+ }
+ else if (valstr == "external")
+ {
+ // open in external browser
+ LLWeb::loadURLExternal(mURLHome);
+ }
+ }
+}
+
+void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ childSetValue("status_text", LLSD( self->getStatusText() ) );
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ if (mFirstNavigate)
+ {
+ mFirstNavigate = false;
+ }
+ else
+ {
+ mPerformanceTimer.start();
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LLStringUtil::format_map_t args;
+ args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32());
+ childSetValue("status_text", LLSD( getString("LoadTime", args)) );
+ }
+ break;
+
+ default:
+ // Having a default case makes the compiler happy.
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileFirstLife::LLPanelProfileFirstLife()
+ : LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+}
+
+LLPanelProfileFirstLife::~LLPanelProfileFirstLife()
+{
+}
+
+BOOL LLPanelProfileFirstLife::postBuild()
+{
+ mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit");
+ mPicture = getChild<LLIconCtrl>("real_world_pic");
+
+ mUploadPhoto = getChild<LLButton>("fl_upload_image");
+ mChangePhoto = getChild<LLButton>("fl_change_image");
+ mRemovePhoto = getChild<LLButton>("fl_remove_image");
+ mSaveChanges = getChild<LLButton>("fl_save_changes");
+ mDiscardChanges = getChild<LLButton>("fl_discard_changes");
+
+ mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr);
+ mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr);
+ mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr);
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileFirstLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ if (!getSelfProfile())
+ {
+ // Otherwise as the only focusable element it will be selected
+ mDescriptionEdit->setTabStop(FALSE);
+ }
+
+ resetData();
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploading(bool loading)
+{
+ mUploadPhoto->setEnabled(!loading);
+ mChangePhoto->setEnabled(!loading);
+ mRemovePhoto->setEnabled(!loading && mImageId.notNull());
+
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mPicture->setValue(image_asset_id);
+ mImageId = image_asset_id;
+ setProfileImageUploading(false);
+}
+
+void LLPanelProfileFirstLife::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileFirstLife::onUploadPhoto()
+{
+ (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onChangePhoto()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitPhoto(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileFirstLife::onRemovePhoto()
+{
+ onCommitPhoto(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["fl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileFirstLife::setDescriptionText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentDescription = text;
+ mDescriptionEdit->setValue(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::onSetDescriptionDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileFirstLife::onSaveDescriptionChanges()
+{
+ mCurrentDescription = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileFirstLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data)
+{
+ setDescriptionText(avatar_data->fl_about_text);
+
+ mImageId = avatar_data->fl_image_id;
+
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ setLoaded();
+}
+
+void LLPanelProfileFirstLife::resetData()
+{
+ setDescriptionText(std::string());
+ mPicture->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ mUploadPhoto->setVisible(getSelfProfile());
+ mChangePhoto->setVisible(getSelfProfile());
+ mRemovePhoto->setVisible(getSelfProfile());
+ mSaveChanges->setVisible(getSelfProfile());
+ mDiscardChanges->setVisible(getSelfProfile());
+}
+
+void LLPanelProfileFirstLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mDescriptionEdit->setEnabled(TRUE);
+ mPicture->setEnabled(TRUE);
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileNotes::LLPanelProfileNotes()
+: LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+
+}
+
+LLPanelProfileNotes::~LLPanelProfileNotes()
+{
+}
+
+void LLPanelProfileNotes::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
+}
+
+void LLPanelProfileNotes::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveNotesChanges();
+ }
+}
+
+BOOL LLPanelProfileNotes::postBuild()
+{
+ mNotesEditor = getChild<LLTextEditor>("notes_edit");
+ mSaveChanges = getChild<LLButton>("notes_save_changes");
+ mDiscardChanges = getChild<LLButton>("notes_discard_changes");
+
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr);
+ mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileNotes::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+}
+
+void LLPanelProfileNotes::setNotesText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentNotes = text;
+ mNotesEditor->setValue(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::onSetNotesDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileNotes::onSaveNotesChanges()
+{
+ mCurrentNotes = mNotesEditor->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileNotes::onDiscardNotesChanges()
+{
+ setNotesText(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes)
+{
+ setNotesText(avatar_notes->notes);
+ mNotesEditor->setEnabled(TRUE);
+ setLoaded();
+}
+
+void LLPanelProfileNotes::resetData()
+{
+ resetLoading();
+ setNotesText(std::string());
+}
+
+void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfile
+
+LLPanelProfile::LLPanelProfile()
+ : LLPanelProfileTab()
+{
+}
+
+LLPanelProfile::~LLPanelProfile()
+{
+}
+
+BOOL LLPanelProfile::postBuild()
+{
+ return TRUE;
+}
+
+void LLPanelProfile::onTabChange()
+{
+ LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel());
+ if (active_panel)
+ {
+ active_panel->updateData();
+ }
}
void LLPanelProfile::onOpen(const LLSD& key)
{
- getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId());
+ LLUUID avatar_id = key["id"].asUUID();
- // support commands to open further pieces of UI
- if (key.has("show_tab_panel"))
- {
- std::string panel = key["show_tab_panel"].asString();
- if (panel == "create_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewClassified();
- }
- }
- else if (panel == "classified_details")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedInfo(params);
- }
- }
- else if (panel == "edit_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedEdit(params);
- }
- }
- else if (panel == "create_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewPick();
- }
- }
- else if (panel == "edit_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openPickEdit(params);
- }
- }
- }
+ // Don't reload the same profile
+ if (getAvatarId() == avatar_id)
+ {
+ return;
+ }
+
+ LLPanelProfileTab::onOpen(avatar_id);
+
+ mTabContainer = getChild<LLTabContainer>("panel_profile_tabs");
+ mPanelSecondlife = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE);
+ mPanelWeb = findChild<LLPanelProfileWeb>(PANEL_WEB);
+ mPanelPicks = findChild<LLPanelProfilePicks>(PANEL_PICKS);
+ mPanelClassifieds = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS);
+ mPanelFirstlife = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE);
+ mPanelNotes = findChild<LLPanelProfileNotes>(PANEL_NOTES);
+
+ mPanelSecondlife->onOpen(avatar_id);
+ mPanelWeb->onOpen(avatar_id);
+ mPanelPicks->onOpen(avatar_id);
+ mPanelClassifieds->onOpen(avatar_id);
+ mPanelFirstlife->onOpen(avatar_id);
+ mPanelNotes->onOpen(avatar_id);
+
+ // Always request the base profile info
+ resetLoading();
+ updateData();
+
+ // Some tabs only request data when opened
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this));
}
-void LLPanelProfile::onTabSelected(const LLSD& param)
+void LLPanelProfile::updateData()
{
- std::string tab_name = param.asString();
- if (NULL != getTabContainer()[tab_name])
- {
- getTabContainer()[tab_name]->onOpen(getAvatarId());
- }
+ LLUUID avatar_id = getAvatarId();
+ // Todo: getIsloading functionality needs to be expanded to
+ // include 'inited' or 'data_provided' state to not rerequest
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ mPanelSecondlife->setIsLoading();
+ mPanelPicks->setIsLoading();
+ mPanelFirstlife->setIsLoading();
+ mPanelNotes->setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
}
-void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
+void LLPanelProfile::refreshName()
{
- // Hide currently visible panel (STORM-690).
- mChildStack.push();
+ mPanelSecondlife->refreshName();
+}
- // Add the panel or bring it to front.
- if (panel->getParent() != this)
- {
- addChild(panel);
- }
- else
- {
- sendChildToFront(panel);
- }
+void LLPanelProfile::createPick(const LLPickData &data)
+{
+ mTabContainer->selectTabPanel(mPanelPicks);
+ mPanelPicks->createPick(data);
+}
- panel->setVisible(TRUE);
- panel->setFocus(TRUE); // prevent losing focus by the floater
- panel->onOpen(params);
+void LLPanelProfile::showPick(const LLUUID& pick_id)
+{
+ if (pick_id.notNull())
+ {
+ mPanelPicks->selectPick(pick_id);
+ }
+ mTabContainer->selectTabPanel(mPanelPicks);
+}
- LLRect new_rect = getRect();
- panel->reshape(new_rect.getWidth(), new_rect.getHeight());
- new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
- panel->setRect(new_rect);
+bool LLPanelProfile::isPickTabSelected()
+{
+ return (mTabContainer->getCurrentPanel() == mPanelPicks);
}
-void LLPanelProfile::closePanel(LLPanel* panel)
+bool LLPanelProfile::isNotesTabSelected()
{
- panel->setVisible(FALSE);
+ return (mTabContainer->getCurrentPanel() == mPanelNotes);
+}
- if (panel->getParent() == this)
- {
- removeChild(panel);
+bool LLPanelProfile::hasUnsavedChanges()
+{
+ return mPanelSecondlife->hasUnsavedChanges()
+ || mPanelPicks->hasUnsavedChanges()
+ || mPanelClassifieds->hasUnsavedChanges()
+ || mPanelFirstlife->hasUnsavedChanges()
+ || mPanelNotes->hasUnsavedChanges();
+}
- // Make the underlying panel visible.
- mChildStack.pop();
+bool LLPanelProfile::hasUnpublishedClassifieds()
+{
+ return mPanelClassifieds->hasNewClassifieds();
+}
- // Prevent losing focus by the floater
- const child_list_t* child_list = getChildList();
- if (child_list->size() > 0)
- {
- child_list->front()->setFocus(TRUE);
- }
- else
- {
- LL_WARNS() << "No underlying panel to focus." << LL_ENDL;
- }
- }
+void LLPanelProfile::commitUnsavedChanges()
+{
+ mPanelSecondlife->commitUnsavedChanges();
+ mPanelPicks->commitUnsavedChanges();
+ mPanelClassifieds->commitUnsavedChanges();
+ mPanelFirstlife->commitUnsavedChanges();
+ mPanelNotes->commitUnsavedChanges();
}
-S32 LLPanelProfile::notifyParent(const LLSD& info)
+void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit)
{
- std::string action = info["action"];
- // lets update Picks list after Pick was saved
- if("save_new_pick" == action)
- {
- onOpen(info);
- return 1;
- }
+ if (classified_id.notNull())
+ {
+ mPanelClassifieds->selectClassified(classified_id, edit);
+ }
+ mTabContainer->selectTabPanel(mPanelClassifieds);
+}
- return LLPanel::notifyParent(info);
+void LLPanelProfile::createClassified()
+{
+ mPanelClassifieds->createClassified();
+ mTabContainer->selectTabPanel(mPanelClassifieds);
}
+
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index d97f60ed22..d32bb943bd 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.h
* @brief Profile panel
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, Linden Research, Inc.
+*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
-*
+*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
-*
+*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
+*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -27,76 +27,383 @@
#ifndef LL_LLPANELPROFILE_H
#define LL_LLPANELPROFILE_H
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
+#include "llfloater.h"
#include "llpanel.h"
#include "llpanelavatar.h"
+#include "llmediactrl.h"
+#include "llvoiceclient.h"
+
+// class LLPanelProfileClassifieds;
+// class LLTabContainer;
+// class LLPanelProfileSecondLife;
+// class LLPanelProfileWeb;
+// class LLPanelProfilePicks;
+// class LLPanelProfileFirstLife;
+// class LLPanelProfileNotes;
+
+class LLAvatarName;
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLIconCtrl;
class LLTabContainer;
+class LLTextBox;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLGroupList;
+class LLTextBase;
+class LLMenuButton;
+class LLLineEditor;
+class LLTextEditor;
+class LLPanelProfileClassifieds;
+class LLPanelProfilePicks;
+class LLViewerFetchedTexture;
-std::string getProfileURL(const std::string& agent_name);
/**
-* Base class for Profile View and My Profile.
+* Panel for displaying Avatar's second life related info.
*/
-class LLPanelProfile : public LLPanel
+class LLPanelProfileSecondLife
+ : public LLPanelProfileTab
+ , public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
- LOG_CLASS(LLPanelProfile);
+public:
+ LLPanelProfileSecondLife();
+ /*virtual*/ ~LLPanelProfileSecondLife();
+
+ void onOpen(const LLSD& key) override;
+
+ /**
+ * LLFriendObserver trigger
+ */
+ void changed(U32 mask) override;
+
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ void onChange(EStatusType status, const std::string &channelURI, bool proximal) override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ BOOL postBuild() override;
+
+ void resetData() override;
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+ void refreshName();
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ /**
+ * Process profile related data received from server.
+ */
+ void processProfileProperties(const LLAvatarData* avatar_data);
+
+ /**
+ * Processes group related data received from server.
+ */
+ void processGroupProperties(const LLAvatarGroups* avatar_groups);
+
+ /**
+ * Fills common for Avatar profile and My Profile fields.
+ */
+ void fillCommonData(const LLAvatarData* avatar_data);
+
+ /**
+ * Fills partner data.
+ */
+ void fillPartnerData(const LLAvatarData* avatar_data);
+ /**
+ * Fills account status.
+ */
+ void fillAccountStatus(const LLAvatarData* avatar_data);
+
+ /**
+ * Sets permissions specific icon
+ */
+ void fillRightsData();
+
+ /**
+ * Fills user name, display name, age.
+ */
+ void fillAgeData(const LLDate &born_on);
+
+ void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
+ static void onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
+ void processOnlineStatus(bool is_friend, bool show_online, bool online);
+
+private:
+ void setLoaded() override;
+ void onCommitMenu(const LLSD& userdata);
+ bool onEnableMenu(const LLSD& userdata);
+ bool onCheckMenu(const LLSD& userdata);
+ void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
+
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onShowInSearchCallback();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+ void onShowAgentPermissionsDialog();
+ void onShowAgentProfileTexture();
+ void onShowTexturePicker();
+ void onCommitProfileImage(const LLUUID& id);
+
+private:
+ typedef std::map<std::string, LLUUID> group_map_t;
+ group_map_t mGroups;
+ void openGroupProfile();
+
+ LLGroupList* mGroupList;
+ LLComboBox* mShowInSearchCombo;
+ LLIconCtrl* mSecondLifePic;
+ LLPanel* mSecondLifePicLayout;
+ LLTextEditor* mDescriptionEdit;
+ LLMenuButton* mAgentActionMenuButton;
+ LLButton* mSaveDescriptionChanges;
+ LLButton* mDiscardDescriptionChanges;
+ LLIconCtrl* mCanSeeOnlineIcon;
+ LLIconCtrl* mCantSeeOnlineIcon;
+ LLIconCtrl* mCanSeeOnMapIcon;
+ LLIconCtrl* mCantSeeOnMapIcon;
+ LLIconCtrl* mCanEditObjectsIcon;
+ LLIconCtrl* mCantEditObjectsIcon;
+
+ LLHandle<LLFloater> mFloaterPermissionsHandle;
+ LLHandle<LLFloater> mFloaterProfileTextureHandle;
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ bool mHasUnsavedDescriptionChanges;
+ bool mVoiceStatus;
+ bool mWaitingForImageUpload;
+ bool mAllowPublish;
+ std::string mDescriptionText;
+ LLUUID mImageId;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+
+/**
+* Panel for displaying Avatar's web profile and home page.
+*/
+class LLPanelProfileWeb
+ : public LLPanelProfileTab
+ , public LLViewerMediaObserver
+{
public:
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onOpen(const LLSD& key);
+ LLPanelProfileWeb();
+ /*virtual*/ ~LLPanelProfileWeb();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
- virtual void openPanel(LLPanel* panel, const LLSD& params);
+ void resetData() override;
- virtual void closePanel(LLPanel* panel);
+ /**
+ * Loads web profile.
+ */
+ void updateData() override;
- S32 notifyParent(const LLSD& info);
+ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
protected:
+ void onCommitLoad(LLUICtrl* ctrl);
- LLPanelProfile();
+private:
+ std::string mURLHome;
+ std::string mURLWebProfile;
+ LLMediaCtrl* mWebBrowser;
- virtual void onTabSelected(const LLSD& param);
+ LLFrameTimer mPerformanceTimer;
+ bool mFirstNavigate;
- const LLUUID& getAvatarId() { return mAvatarId; }
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+/**
+* Panel for displaying Avatar's first life related info.
+*/
+class LLPanelProfileFirstLife
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileFirstLife();
+ /*virtual*/ ~LLPanelProfileFirstLife();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
+
+ void processProperties(const LLAvatarData* avatar_data);
+
+ void resetData() override;
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ void setLoaded() override;
+
+ void onUploadPhoto();
+ void onChangePhoto();
+ void onRemovePhoto();
+ void onCommitPhoto(const LLUUID& id);
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+
+ LLTextEditor* mDescriptionEdit;
+ LLIconCtrl* mPicture;
+ LLButton* mUploadPhoto;
+ LLButton* mChangePhoto;
+ LLButton* mRemovePhoto;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ std::string mCurrentDescription;
+ LLUUID mImageId;
+ bool mHasUnsavedChanges;
+};
+
+/**
+ * Panel for displaying Avatar's notes and modifying friend's rights.
+ */
+class LLPanelProfileNotes
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileNotes();
+ /*virtual*/ ~LLPanelProfileNotes();
- void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+ void setAvatarId(const LLUUID& avatar_id) override;
- typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
+ void onOpen(const LLSD& key) override;
- profile_tabs_t& getTabContainer() { return mTabContainer; }
+ BOOL postBuild() override;
+
+ void processProperties(LLAvatarNotes* avatar_notes);
+
+ void resetData() override;
+
+ void updateData() override;
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+protected:
+ void setNotesText(const std::string &text);
+ void onSetNotesDirty();
+ void onSaveNotesChanges();
+ void onDiscardNotesChanges();
+
+ LLTextEditor* mNotesEditor;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ std::string mCurrentNotes;
+ bool mHasUnsavedChanges;
+};
+
+
+/**
+* Container panel for the profile tabs
+*/
+class LLPanelProfile
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfile();
+ /*virtual*/ ~LLPanelProfile();
+
+ BOOL postBuild() override;
+
+ void updateData() override;
+ void refreshName();
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ bool isNotesTabSelected();
+ bool hasUnsavedChanges() override;
+ bool hasUnpublishedClassifieds();
+ void commitUnsavedChanges() override;
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+ LLAvatarData getAvatarData() { return mAvatarData; };
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
private:
+ void onTabChange();
+
+ LLPanelProfileSecondLife* mPanelSecondlife;
+ LLPanelProfileWeb* mPanelWeb;
+ LLPanelProfilePicks* mPanelPicks;
+ LLPanelProfileClassifieds* mPanelClassifieds;
+ LLPanelProfileFirstLife* mPanelFirstlife;
+ LLPanelProfileNotes* mPanelNotes;
+ LLTabContainer* mTabContainer;
- //-- ChildStack begins ----------------------------------------------------
- class ChildStack
- {
- LOG_CLASS(LLPanelProfile::ChildStack);
- public:
- ChildStack();
- ~ChildStack();
- void setParent(LLPanel* parent);
-
- bool push();
- bool pop();
- void preParentReshape();
- void postParentReshape();
-
- private:
- void dump();
-
- typedef LLView::child_list_t view_list_t;
- typedef std::list<view_list_t> stack_t;
-
- stack_t mStack;
- stack_t mSavedStack;
- LLPanel* mParent;
- };
- //-- ChildStack ends ------------------------------------------------------
-
- profile_tabs_t mTabContainer;
- ChildStack mChildStack;
- LLUUID mAvatarId;
+ // Todo: due to server taking minutes to update this needs a more long term storage
+ // to reuse recently saved values if user opens floater again
+ // Storage implementation depends onto how a cap will be implemented, if cap will be
+ // enought to fully update LLAvatarPropertiesProcessor, then this storage can be
+ // implemented there.
+ LLAvatarData mAvatarData;
};
#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
new file mode 100644
index 0000000000..a3913ddc49
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -0,0 +1,1513 @@
+/**
+ * @file llpanelprofileclassifieds.cpp
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofileclassifieds.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedflags.h"
+#include "llcombobox.h"
+#include "llcommandhandler.h" // for classified HTML detail page click tracking
+#include "llcorehttputil.h"
+#include "lldispatcher.h"
+#include "llfloaterclassified.h"
+#include "llfloaterreg.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfloaterworldmap.h"
+#include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llparcel.h"
+#include "llregistry.h"
+#include "llscrollcontainer.h"
+#include "llstartup.h"
+#include "llstatusbar.h"
+#include "lltabcontainer.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
+#include "llviewertexture.h"
+
+
+//*TODO: verify this limit
+const S32 MAX_AVATAR_CLASSIFIEDS = 100;
+
+const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
+const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530;
+
+//static
+LLPanelProfileClassified::panel_list_t LLPanelProfileClassified::sAllPanels;
+
+static LLPanelInjector<LLPanelProfileClassifieds> t_panel_profile_classifieds("panel_profile_classifieds");
+static LLPanelInjector<LLPanelProfileClassified> t_panel_profile_classified("panel_profile_classified");
+
+class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesObserver
+{
+public:
+ // throttle calls from untrusted browsers
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
+
+ std::set<LLUUID> mClassifiedIds;
+ std::string mRequestVerb;
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
+ {
+ LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/classified/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createClassified();
+ return true;
+ }
+
+ // then handle the general app/classified/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the classified
+ LLUUID classified_id;
+ if (!classified_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // show the classified in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "about")
+ {
+ mRequestVerb = verb;
+ mClassifiedIds.insert(classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
+ return true;
+ }
+ else if (verb == "edit")
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), classified_id, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ void openClassified(LLAvatarClassifiedInfo* c_info)
+ {
+ if (mRequestVerb == "about")
+ {
+ if (c_info->creator_id == gAgent.getID())
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), c_info->classified_id, false);
+ }
+ else
+ {
+ LLSD params;
+ params["id"] = c_info->creator_id;
+ params["classified_id"] = c_info->classified_id;
+ params["classified_creator_id"] = c_info->creator_id;
+ params["classified_snapshot_id"] = c_info->snapshot_id;
+ params["classified_name"] = c_info->name;
+ params["classified_desc"] = c_info->description;
+ params["from_search"] = true;
+
+ LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params);
+ if (floaterp)
+ {
+ floaterp->openFloater(params);
+ floaterp->setVisibleAndFrontmost();
+ }
+ }
+ }
+ }
+
+ void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ // is this the classified that we asked for?
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
+ {
+ return;
+ }
+
+ // open the detail side tray for this classified
+ openClassified(c_info);
+
+ // remove our observer now that we're done
+ mClassifiedIds.erase(c_info->classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
+ }
+};
+LLClassifiedHandler gClassifiedHandler;
+
+//////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassifieds
+//-----------------------------------------------------------------------------
+
+LLPanelProfileClassifieds::LLPanelProfileClassifieds()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mClassifiedToSelectOnLoad(LLUUID::null)
+ , mClassifiedEditOnLoad(false)
+ , mSheduledClassifiedCreation(false)
+{
+}
+
+LLPanelProfileClassifieds::~LLPanelProfileClassifieds()
+{
+}
+
+void LLPanelProfileClassifieds::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+
+}
+
+void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel)
+ {
+ if (classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->selectTabPanel(classified_panel);
+ if (edit)
+ {
+ classified_panel->setEditMode(TRUE);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mClassifiedToSelectOnLoad = classified_id;
+ mClassifiedEditOnLoad = edit;
+ }
+}
+
+void LLPanelProfileClassifieds::createClassified()
+{
+ if (getIsLoaded())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+ }
+ else
+ {
+ mSheduledClassifiedCreation = true;
+ }
+}
+
+BOOL LLPanelProfileClassifieds::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_classifieds");
+ mNoItemsLabel = getChild<LLUICtrl>("classifieds_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassifieds::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+}
+
+void LLPanelProfileClassifieds::onClickDelete()
+{
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getCurrentPanel());
+ if (classified_panel)
+ {
+ LLUUID classified_id = classified_panel->getClassifiedId();
+ LLSD args;
+ args["CLASSIFIED"] = classified_panel->getClassifiedName();
+ LLSD payload;
+ payload["classified_id"] = classified_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeleteClassified", args, payload,
+ boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2));
+ }
+}
+
+void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID classified_id = notification["payload"]["classified_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->removeTabPanel(classified_panel);
+ }
+
+ if (classified_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id);
+ }
+
+ updateButtons();
+
+ BOOL no_data = !mTabContainer->getTabCount();
+ mNoItemsLabel->setVisible(no_data);
+ }
+}
+
+void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorType type)
+{
+ if ((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
+ {
+ LLUUID avatar_id = getAvatarId();
+
+ LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+ if (c_info && getAvatarId() == c_info->target_id)
+ {
+ // do not clear classified list in case we will receive two or more data packets.
+ // list has been cleared in updateData(). (fix for EXT-6436)
+ LLUUID selected_id = mClassifiedToSelectOnLoad;
+ bool has_selection = false;
+
+ LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
+ for (; c_info->classifieds_list.end() != it; ++it)
+ {
+ LLAvatarClassifieds::classified_data c_data = *it;
+
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+
+ LLSD params;
+ params["classified_creator_id"] = avatar_id;
+ params["classified_id"] = c_data.classified_id;
+ params["classified_name"] = c_data.name;
+ params["from_search"] = (selected_id == c_data.classified_id); //SLURL handling and stats tracking
+ params["edit"] = (selected_id == c_data.classified_id) && mClassifiedEditOnLoad;
+ classified_panel->onOpen(params);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(selected_id == c_data.classified_id).
+ label(c_data.name));
+
+ if (selected_id == c_data.classified_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ if (mSheduledClassifiedCreation)
+ {
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(!has_selection).
+ label(classified_panel->getClassifiedName()));
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mClassifiedToSelectOnLoad = LLUUID::null;
+ mClassifiedEditOnLoad = false;
+ mSheduledClassifiedCreation = false;
+
+ // set even if not visible, user might delete own
+ // calassified and this string will need to be shown
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+ }
+ }
+}
+
+void LLPanelProfileClassifieds::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfileClassifieds::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewClassified());
+ mDeleteButton->setEnabled(canDeleteClassified());
+ }
+}
+
+void LLPanelProfileClassifieds::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id);
+ }
+}
+
+bool LLPanelProfileClassifieds::hasNewClassifieds()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isNew())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty()) // includes 'new'
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::canAddNewClassified()
+{
+ return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS);
+}
+
+bool LLPanelProfileClassifieds::canDeleteClassified()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+void LLPanelProfileClassifieds::commitUnsavedChanges()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty() && !classified_panel->isNew())
+ {
+ classified_panel->doSave();
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// LLDispatchClassifiedClickThrough
+//-----------------------------------------------------------------------------
+
+// "classifiedclickthrough"
+// strings[0] = classified_id
+// strings[1] = teleport_clicks
+// strings[2] = map_clicks
+// strings[3] = profile_clicks
+class LLDispatchClassifiedClickThrough : public LLDispatchHandler
+{
+public:
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
+ {
+ if (strings.size() != 4) return false;
+ LLUUID classified_id(strings[0]);
+ S32 teleport_clicks = atoi(strings[1].c_str());
+ S32 map_clicks = atoi(strings[2].c_str());
+ S32 profile_clicks = atoi(strings[3].c_str());
+
+ LLPanelProfileClassified::setClickThrough(
+ classified_id, teleport_clicks, map_clicks, profile_clicks, false);
+
+ return true;
+ }
+};
+static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassified
+//-----------------------------------------------------------------------------
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG = 1;
+
+LLPanelProfileClassified::LLPanelProfileClassified()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mInfoLoaded(false)
+ , mTeleportClicksOld(0)
+ , mMapClicksOld(0)
+ , mProfileClicksOld(0)
+ , mTeleportClicksNew(0)
+ , mMapClicksNew(0)
+ , mProfileClicksNew(0)
+ , mPriceForListing(0)
+ , mSnapshotCtrl(NULL)
+ , mPublishFloater(NULL)
+ , mIsNew(false)
+ , mIsNewWithErrors(false)
+ , mCanClose(false)
+ , mEditMode(false)
+ , mEditOnLoad(false)
+{
+ sAllPanels.push_back(this);
+}
+
+LLPanelProfileClassified::~LLPanelProfileClassified()
+{
+ sAllPanels.remove(this);
+ gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
+}
+
+//static
+LLPanelProfileClassified* LLPanelProfileClassified::create()
+{
+ LLPanelProfileClassified* panel = new LLPanelProfileClassified();
+ panel->buildFromFile("panel_profile_classified.xml");
+ return panel;
+}
+
+BOOL LLPanelProfileClassified::postBuild()
+{
+ mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+ mInfoPanel = getChild<LLView>("info_panel");
+ mInfoScroll = getChild<LLPanel>("info_scroll_content_panel");
+ mEditPanel = getChild<LLPanel>("edit_panel");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("classified_snapshot");
+ mEditIcon = getChild<LLUICtrl>("edit_icon");
+
+ //info
+ mClassifiedNameText = getChild<LLUICtrl>("classified_name");
+ mClassifiedDescText = getChild<LLTextEditor>("classified_desc");
+ mLocationText = getChild<LLUICtrl>("classified_location");
+ mCategoryText = getChild<LLUICtrl>("category");
+ mContentTypeText = getChild<LLUICtrl>("content_type");
+ mContentTypeM = getChild<LLIconCtrl>("content_type_moderate");
+ mContentTypeG = getChild<LLIconCtrl>("content_type_general");
+ mPriceText = getChild<LLUICtrl>("price_for_listing");
+ mAutoRenewText = getChild<LLUICtrl>("auto_renew");
+
+ mMapButton = getChild<LLButton>("show_on_map_btn");
+ mTeleportButton = getChild<LLButton>("teleport_btn");
+ mEditButton = getChild<LLButton>("edit_btn");
+
+ //edit
+ mClassifiedNameEdit = getChild<LLLineEditor>("classified_name_edit");
+ mClassifiedDescEdit = getChild<LLTextEditor>("classified_desc_edit");
+ mLocationEdit = getChild<LLUICtrl>("classified_location_edit");
+ mCategoryCombo = getChild<LLComboBox>("category_edit");
+ mContentTypeCombo = getChild<LLComboBox>("content_type_edit");
+ mAutoRenewEdit = getChild<LLUICtrl>("auto_renew_edit");
+
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mSetLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+ mCancelButton = getChild<LLButton>("cancel_btn");
+
+ mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp");
+ mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel");
+ mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp");
+ mSaveBtnCnt = getChild<LLPanel>("save_btn_lp");
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelProfileClassified::onTextureSelected, this));
+ mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseEnter, this));
+ mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseLeave, this));
+ mEditIcon->setVisible(false);
+
+ mMapButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onMapClick, this));
+ mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onTeleportClick, this));
+ mEditButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onEditClick, this));
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSaveClick, this));
+ mSetLocationButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSetLocationClick, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onCancelClick, this));
+
+ LLClassifiedInfo::cat_map::iterator iter;
+ for (iter = LLClassifiedInfo::sCategories.begin();
+ iter != LLClassifiedInfo::sCategories.end();
+ iter++)
+ {
+ mCategoryCombo->add(LLTrans::getString(iter->second));
+ }
+
+ mClassifiedNameEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this), NULL);
+ mClassifiedDescEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mCategoryCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mContentTypeCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mAutoRenewEdit->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassified::onOpen(const LLSD& key)
+{
+ mIsNew = key.isUndefined();
+
+ resetData();
+ resetControls();
+ scrollToTop();
+
+ // classified is not created yet
+ bool is_new = isNew() || isNewWithErrors();
+
+ if(is_new)
+ {
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID());
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID snapshot_id = LLUUID::null;
+ std::string desc;
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedName(makeClassifiedName());
+ setDescription(desc);
+ setSnapshotId(snapshot_id);
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+ // server will set valid parcel id
+ setParcelId(LLUUID::null);
+
+ mSaveButton->setLabelArg("[LABEL]", getString("publish_label"));
+
+ setEditMode(TRUE);
+ enableSave(true);
+ enableEditing(true);
+ resetDirty();
+ setInfoLoaded(false);
+ }
+ else
+ {
+ LLUUID avatar_id = key["classified_creator_id"];
+ if(avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ setClassifiedId(key["classified_id"]);
+ setClassifiedName(key["classified_name"]);
+ setFromSearch(key["from_search"]);
+ mEditOnLoad = key["edit"];
+
+ LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+
+ gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
+
+ if (gAgent.getRegion())
+ {
+ // While we're at it let's get the stats from the new table if that
+ // capability exists.
+ std::string url = gAgent.getRegion()->getCapability("SearchStatRequest");
+ if (!url.empty())
+ {
+ LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
+ LLSD body;
+ LLUUID classifiedId = getClassifiedId();
+ body["classified_id"] = classifiedId;
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+ boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, classifiedId, _1));
+ }
+ }
+ // Update classified click stats.
+ // *TODO: Should we do this when opening not from search?
+ if (!fromSearch() )
+ {
+ sendClickMessage("profile");
+ }
+
+ setInfoLoaded(false);
+ }
+
+
+ bool is_self = getSelfProfile();
+ getChildView("auto_renew_layout_panel")->setVisible(is_self);
+ getChildView("clickthrough_layout_panel")->setVisible(is_self);
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ // see LLPanelProfileClassified::sendUpdate() for notes
+ if (mIsNewWithErrors)
+ {
+ // We just published it
+ setEditMode(FALSE);
+ }
+ mIsNewWithErrors = false;
+ mIsNew = false;
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
+ setPosGlobal(c_info->pos_global);
+ setSimName(c_info->sim_name);
+
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+
+ mCategoryText->setValue(LLClassifiedInfo::sCategories[c_info->category]);
+ // *HACK see LLPanelProfileClassified::sendUpdate()
+ setCategory(c_info->category - 1);
+
+ bool mature = is_cf_mature(c_info->flags);
+ setContentType(mature);
+
+ bool auto_renew = is_cf_auto_renew(c_info->flags);
+ std::string auto_renew_str = auto_renew ? getString("auto_renew_on") : getString("auto_renew_off");
+ mAutoRenewText->setValue(auto_renew_str);
+ mAutoRenewEdit->setValue(auto_renew);
+
+ static LLUIString price_str = getString("l$_price");
+ price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing));
+ mPriceText->setValue(LLSD(price_str));
+
+ static std::string date_fmt = getString("date_fmt");
+ std::string date_str = date_fmt;
+ LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date));
+ getChild<LLUICtrl>("creation_date")->setValue(date_str);
+
+ resetDirty();
+ setInfoLoaded(true);
+ enableSave(false);
+ enableEditing(true);
+
+ // for just created classified - in case user opened edit panel before processProperties() callback
+ mSaveButton->setLabelArg("[LABEL]", getString("save_label"));
+
+ setLoaded();
+ updateButtons();
+
+ if (mEditOnLoad)
+ {
+ setEditMode(TRUE);
+ }
+ }
+
+}
+
+void LLPanelProfileClassified::setEditMode(BOOL edit_mode)
+{
+ mEditMode = edit_mode;
+
+ mInfoPanel->setVisible(!edit_mode);
+ mEditPanel->setVisible(edit_mode);
+
+ // snapshot control is common between info and edit,
+ // enable it only when in edit mode
+ mSnapshotCtrl->setEnabled(edit_mode);
+
+ scrollToTop();
+ updateButtons();
+ updateInfoRect();
+}
+
+void LLPanelProfileClassified::updateButtons()
+{
+ bool edit_mode = getEditMode();
+ mUtilityBtnCnt->setVisible(!edit_mode);
+
+ // cancel button should either delete unpublished
+ // classified or not be there at all
+ mCancelBtnCnt->setVisible(edit_mode && !mIsNew);
+ mPublishBtnsCnt->setVisible(edit_mode);
+ mSaveBtnCnt->setVisible(edit_mode);
+ mEditButton->setVisible(!edit_mode && getSelfProfile());
+}
+
+void LLPanelProfileClassified::updateInfoRect()
+{
+ if (getEditMode())
+ {
+ // info_scroll_content_panel contains both info and edit panel
+ // info panel can be very large and scroll bar will carry over.
+ // Resize info panel to prevent scroll carry over when in edit mode.
+ mInfoScroll->reshape(mInfoScroll->getRect().getWidth(), DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT, FALSE);
+ }
+ else
+ {
+ // Adjust text height to make description scrollable.
+ S32 new_height = mClassifiedDescText->getTextBoundingRect().getHeight();
+ LLRect visible_rect = mClassifiedDescText->getVisibleDocumentRect();
+ S32 delta_height = new_height - visible_rect.getHeight() + 5;
+
+ LLRect rect = mInfoScroll->getRect();
+ mInfoScroll->reshape(rect.getWidth(), rect.getHeight() + delta_height, FALSE);
+ }
+}
+
+void LLPanelProfileClassified::enableEditing(bool enable)
+{
+ mEditButton->setEnabled(enable);
+ mClassifiedNameEdit->setEnabled(enable);
+ mClassifiedDescEdit->setEnabled(enable);
+ mSetLocationButton->setEnabled(enable);
+ mCategoryCombo->setEnabled(enable);
+ mContentTypeCombo->setEnabled(enable);
+ mAutoRenewEdit->setEnabled(enable);
+}
+
+void LLPanelProfileClassified::resetControls()
+{
+ updateButtons();
+
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+}
+
+void LLPanelProfileClassified::onEditClick()
+{
+ setEditMode(TRUE);
+}
+
+void LLPanelProfileClassified::onCancelClick()
+{
+ if (isNew())
+ {
+ mClassifiedNameEdit->setValue(mClassifiedNameText->getValue());
+ mClassifiedDescEdit->setValue(mClassifiedDescText->getValue());
+ mLocationEdit->setValue(mLocationText->getValue());
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+ }
+ else
+ {
+ // Reload data to undo changes to forms
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+ }
+
+ setInfoLoaded(false);
+
+ setEditMode(FALSE);
+}
+
+void LLPanelProfileClassified::onSaveClick()
+{
+ mCanClose = false;
+
+ if(!isValidName())
+ {
+ notifyInvalidName();
+ return;
+ }
+ if(isNew() || isNewWithErrors())
+ {
+ if(gStatusBar->getBalance() < getPriceForListing())
+ {
+ LLNotificationsUtil::add("ClassifiedInsufficientFunds");
+ return;
+ }
+
+ mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ if(!mPublishFloater)
+ {
+ mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ mPublishFloater->setPublishClickedCallback(boost::bind
+ (&LLPanelProfileClassified::onPublishFloaterPublishClicked, this));
+ }
+
+ // set spinner value before it has focus or value wont be set
+ mPublishFloater->setPrice(getPriceForListing());
+ mPublishFloater->openFloater(mPublishFloater->getKey());
+ mPublishFloater->center();
+ }
+ else
+ {
+ doSave();
+ }
+}
+
+/*static*/
+void LLPanelProfileClassified::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+ S32 teleport = result["teleport_clicks"].asInteger();
+ S32 map = result["map_clicks"].asInteger();
+ S32 profile = result["profile_clicks"].asInteger();
+ S32 search_teleport = result["search_teleport_clicks"].asInteger();
+ S32 search_map = result["search_map_clicks"].asInteger();
+ S32 search_profile = result["search_profile_clicks"].asInteger();
+
+ LLPanelProfileClassified::setClickThrough(classifiedId,
+ teleport + search_teleport,
+ map + search_map,
+ profile + search_profile,
+ true);
+}
+
+void LLPanelProfileClassified::resetData()
+{
+ setClassifiedName(LLStringUtil::null);
+ setDescription(LLStringUtil::null);
+ setClassifiedLocation(LLStringUtil::null);
+ setClassifiedId(LLUUID::null);
+ setSnapshotId(LLUUID::null);
+ setPosGlobal(LLVector3d::zero);
+ setParcelId(LLUUID::null);
+ setSimName(LLStringUtil::null);
+ setFromSearch(false);
+
+ // reset click stats
+ mTeleportClicksOld = 0;
+ mMapClicksOld = 0;
+ mProfileClicksOld = 0;
+ mTeleportClicksNew = 0;
+ mMapClicksNew = 0;
+ mProfileClicksNew = 0;
+
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+
+ mCategoryText->setValue(LLStringUtil::null);
+ mContentTypeText->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("click_through_text")->setValue(LLStringUtil::null);
+ mEditButton->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("creation_date")->setValue(LLStringUtil::null);
+ mContentTypeM->setVisible(FALSE);
+ mContentTypeG->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::setClassifiedName(const std::string& name)
+{
+ mClassifiedNameText->setValue(name);
+ mClassifiedNameEdit->setValue(name);
+}
+
+std::string LLPanelProfileClassified::getClassifiedName()
+{
+ return mClassifiedNameEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setDescription(const std::string& desc)
+{
+ mClassifiedDescText->setValue(desc);
+ mClassifiedDescEdit->setValue(desc);
+
+ updateInfoRect();
+}
+
+std::string LLPanelProfileClassified::getDescription()
+{
+ return mClassifiedDescEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setClassifiedLocation(const std::string& location)
+{
+ mLocationText->setValue(location);
+ mLocationEdit->setValue(location);
+}
+
+std::string LLPanelProfileClassified::getClassifiedLocation()
+{
+ return mLocationText->getValue().asString();
+}
+
+void LLPanelProfileClassified::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setValue(id);
+}
+
+LLUUID LLPanelProfileClassified::getSnapshotId()
+{
+ return mSnapshotCtrl->getValue().asUUID();
+}
+
+// static
+void LLPanelProfileClassified::setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table)
+{
+ LL_INFOS() << "Click-through data for classified " << classified_id << " arrived: ["
+ << teleport << ", " << map << ", " << profile << "] ("
+ << (from_new_table ? "new" : "old") << ")" << LL_ENDL;
+
+ for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ {
+ LLPanelProfileClassified* self = *iter;
+ if (self->getClassifiedId() != classified_id)
+ {
+ continue;
+ }
+
+ // *HACK: Skip LLPanelProfileClassified instances: they don't display clicks data.
+ // Those instances should not be in the list at all.
+ if (typeid(*self) != typeid(LLPanelProfileClassified))
+ {
+ continue;
+ }
+
+ LL_INFOS() << "Updating classified info panel" << LL_ENDL;
+
+ // We need to check to see if the data came from the new stat_table
+ // or the old classified table. We also need to cache the data from
+ // the two separate sources so as to display the aggregate totals.
+
+ if (from_new_table)
+ {
+ self->mTeleportClicksNew = teleport;
+ self->mMapClicksNew = map;
+ self->mProfileClicksNew = profile;
+ }
+ else
+ {
+ self->mTeleportClicksOld = teleport;
+ self->mMapClicksOld = map;
+ self->mProfileClicksOld = profile;
+ }
+
+ static LLUIString ct_str = self->getString("click_through_text_fmt");
+
+ ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld));
+ ct_str.setArg("[MAP]", llformat("%d", self->mMapClicksNew + self->mMapClicksOld));
+ ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld));
+
+ self->getChild<LLUICtrl>("click_through_text")->setValue(ct_str.getString());
+ // *HACK: remove this when there is enough room for click stats in the info panel
+ self->getChildView("click_through_text")->setToolTip(ct_str.getString());
+
+ LL_INFOS() << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)
+ << ", map: " << llformat("%d", self->mMapClicksNew + self->mMapClicksOld)
+ << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)
+ << LL_ENDL;
+ }
+}
+
+// static
+std::string LLPanelProfileClassified::createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global)
+{
+ std::string location_text;
+
+ location_text.append(original_name);
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+
+ return location_text;
+}
+
+void LLPanelProfileClassified::scrollToTop()
+{
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToTop();
+ }
+}
+
+//info
+// static
+// *TODO: move out of the panel
+void LLPanelProfileClassified::sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name)
+{
+ if (gAgent.getRegion())
+ {
+ // You're allowed to click on your own ads to reassure yourself
+ // that the system is working.
+ LLSD body;
+ body["type"] = type;
+ body["from_search"] = from_search;
+ body["classified_id"] = classified_id;
+ body["parcel_id"] = parcel_id;
+ body["dest_pos_global"] = global_pos.getValue();
+ body["region_name"] = sim_name;
+
+ std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
+ LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
+ LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
+ }
+}
+
+void LLPanelProfileClassified::sendClickMessage(const std::string& type)
+{
+ sendClickMessage(
+ type,
+ fromSearch(),
+ getClassifiedId(),
+ getParcelId(),
+ getPosGlobal(),
+ getSimName());
+}
+
+void LLPanelProfileClassified::onMapClick()
+{
+ sendClickMessage("map");
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfileClassified::onTeleportClick()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ sendClickMessage("teleport");
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+BOOL LLPanelProfileClassified::isDirty() const
+{
+ if(mIsNew)
+ {
+ return TRUE;
+ }
+
+ BOOL dirty = false;
+ dirty |= mSnapshotCtrl->isDirty();
+ dirty |= mClassifiedNameEdit->isDirty();
+ dirty |= mClassifiedDescEdit->isDirty();
+ dirty |= mCategoryCombo->isDirty();
+ dirty |= mContentTypeCombo->isDirty();
+ dirty |= mAutoRenewEdit->isDirty();
+
+ return dirty;
+}
+
+void LLPanelProfileClassified::resetDirty()
+{
+ mSnapshotCtrl->resetDirty();
+ mClassifiedNameEdit->resetDirty();
+
+ // call blockUndo() to really reset dirty(and make isDirty work as intended)
+ mClassifiedDescEdit->blockUndo();
+ mClassifiedDescEdit->resetDirty();
+
+ mCategoryCombo->resetDirty();
+ mContentTypeCombo->resetDirty();
+ mAutoRenewEdit->resetDirty();
+}
+
+bool LLPanelProfileClassified::canClose()
+{
+ return mCanClose;
+}
+
+U32 LLPanelProfileClassified::getContentType()
+{
+ return mContentTypeCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setContentType(bool mature)
+{
+ static std::string mature_str = getString("type_mature");
+ static std::string pg_str = getString("type_pg");
+ mContentTypeText->setValue(mature ? mature_str : pg_str);
+ mContentTypeM->setVisible(mature);
+ mContentTypeG->setVisible(!mature);
+ mContentTypeCombo->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+ mContentTypeCombo->resetDirty();
+}
+
+bool LLPanelProfileClassified::getAutoRenew()
+{
+ return mAutoRenewEdit->getValue().asBoolean();
+}
+
+void LLPanelProfileClassified::sendUpdate()
+{
+ LLAvatarClassifiedInfo c_data;
+
+ if(getClassifiedId().isNull())
+ {
+ setClassifiedId(LLUUID::generateNewID());
+ }
+
+ c_data.agent_id = gAgent.getID();
+ c_data.classified_id = getClassifiedId();
+ // *HACK
+ // Categories on server start with 1 while combo-box index starts with 0
+ c_data.category = getCategory() + 1;
+ c_data.name = getClassifiedName();
+ c_data.description = getDescription();
+ c_data.parcel_id = getParcelId();
+ c_data.snapshot_id = getSnapshotId();
+ c_data.pos_global = getPosGlobal();
+ c_data.flags = getFlags();
+ c_data.price_for_listing = getPriceForListing();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+
+ if(isNew())
+ {
+ // Lets assume there will be some error.
+ // Successful sendClassifiedInfoUpdate will trigger processProperties and
+ // let us know there was no error.
+ mIsNewWithErrors = true;
+ }
+}
+
+U32 LLPanelProfileClassified::getCategory()
+{
+ return mCategoryCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setCategory(U32 category)
+{
+ mCategoryCombo->setCurrentByIndex(category);
+ mCategoryCombo->resetDirty();
+}
+
+U8 LLPanelProfileClassified::getFlags()
+{
+ bool auto_renew = mAutoRenewEdit->getValue().asBoolean();
+
+ bool mature = mContentTypeCombo->getCurrentIndex() == CB_ITEM_MATURE;
+
+ return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelProfileClassified::enableSave(bool enable)
+{
+ mSaveButton->setEnabled(enable);
+}
+
+std::string LLPanelProfileClassified::makeClassifiedName()
+{
+ std::string name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ name = parcel->getName();
+ }
+
+ if(!name.empty())
+ {
+ return name;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region)
+ {
+ name = region->getName();
+ }
+
+ return name;
+}
+
+void LLPanelProfileClassified::onSetLocationClick()
+{
+ setPosGlobal(gAgent.getPositionGlobal());
+ setParcelId(LLUUID::null);
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // mark classified as dirty
+ setValue(LLSD());
+
+ onChange();
+}
+
+void LLPanelProfileClassified::onChange()
+{
+ enableSave(isDirty());
+}
+
+void LLPanelProfileClassified::doSave()
+{
+ //*TODO: Fix all of this
+
+ mCanClose = true;
+ sendUpdate();
+ updateTabLabel(getClassifiedName());
+ resetDirty();
+
+ if (!canClose())
+ {
+ return;
+ }
+
+ if (!isNew() && !isNewWithErrors())
+ {
+ setEditMode(FALSE);
+ return;
+ }
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::onPublishFloaterPublishClicked()
+{
+ setPriceForListing(mPublishFloater->getPrice());
+
+ doSave();
+}
+
+std::string LLPanelProfileClassified::getLocationNotice()
+{
+ static std::string location_notice = getString("location_notice");
+ return location_notice;
+}
+
+bool LLPanelProfileClassified::isValidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ return false;
+ }
+ if (!isalnum(name[0]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLPanelProfileClassified::notifyInvalidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ LLNotificationsUtil::add("BlankClassifiedName");
+ }
+ else if (!isalnum(name[0]))
+ {
+ LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
+ }
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseEnter()
+{
+ mEditIcon->setVisible(TRUE);
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseLeave()
+{
+ mEditIcon->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::onTextureSelected()
+{
+ setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+ onChange();
+}
+
+void LLPanelProfileClassified::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPublishClassifiedFloater
+//-----------------------------------------------------------------------------
+
+LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
+{
+}
+
+BOOL LLPublishClassifiedFloater::postBuild()
+{
+ LLFloater::postBuild();
+
+ childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
+ childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
+
+ return TRUE;
+}
+
+void LLPublishClassifiedFloater::setPrice(S32 price)
+{
+ getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+S32 LLPublishClassifiedFloater::getPrice()
+{
+ return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("publish_btn")->setClickedCallback(cb);
+}
+
+void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h
new file mode 100644
index 0000000000..912819e86b
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.h
@@ -0,0 +1,340 @@
+/**
+ * @file llpanelprofileclassifieds.h
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_PANELPROFILECLASSIFIEDS_H
+#define LL_PANELPROFILECLASSIFIEDS_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedinfo.h"
+#include "llfloater.h"
+#include "llpanel.h"
+#include "llpanelavatar.h"
+#include "llrect.h"
+#include "lluuid.h"
+#include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+
+class LLCheckBoxCtrl;
+class LLLineEditor;
+class LLMediaCtrl;
+class LLScrollContainer;
+class LLTabContainer;
+class LLTextEditor;
+class LLTextureCtrl;
+class LLUICtrl;
+
+
+class LLPublishClassifiedFloater : public LLFloater
+{
+public:
+ LLPublishClassifiedFloater(const LLSD& key);
+ virtual ~LLPublishClassifiedFloater();
+
+ BOOL postBuild() override;
+
+ void setPrice(S32 price);
+ S32 getPrice();
+
+ void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
+ void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
+};
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfileClassifieds
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfileClassifieds();
+ /*virtual*/ ~LLPanelProfileClassifieds();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void selectClassified(const LLUUID& classified_id, bool edit);
+
+ void createClassified();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void resetData() override;
+
+ void updateButtons();
+
+ void updateData() override;
+
+ bool hasNewClassifieds();
+ bool hasUnsavedChanges() override;
+ // commits changes to existing classifieds, but does not publish new classified!
+ void commitUnsavedChanges() override;
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeleteClassified(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewClassified();
+ bool canDeleteClassified();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mClassifiedToSelectOnLoad;
+ bool mClassifiedEditOnLoad;
+ bool mSheduledClassifiedCreation;
+};
+
+
+class LLPanelProfileClassified
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+
+ static LLPanelProfileClassified* create();
+
+ LLPanelProfileClassified();
+
+ /*virtual*/ ~LLPanelProfileClassified();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void setSnapshotId(const LLUUID& id);
+
+ LLUUID getSnapshotId();
+
+ void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
+
+ LLUUID& getClassifiedId() { return mClassifiedId; }
+
+ void setClassifiedName(const std::string& name);
+
+ std::string getClassifiedName();
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription();
+
+ void setClassifiedLocation(const std::string& location);
+
+ std::string getClassifiedLocation();
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setParcelId(const LLUUID& id) { mParcelId = id; }
+
+ LLUUID getParcelId() { return mParcelId; }
+
+ void setSimName(const std::string& sim_name) { mSimName = sim_name; }
+
+ std::string getSimName() { return mSimName; }
+
+ void setFromSearch(bool val) { mFromSearch = val; }
+
+ bool fromSearch() { return mFromSearch; }
+
+ bool getInfoLoaded() { return mInfoLoaded; }
+
+ void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
+
+ BOOL isDirty() const override;
+
+ void resetDirty() override;
+
+ bool isNew() { return mIsNew; }
+
+ bool isNewWithErrors() { return mIsNewWithErrors; }
+
+ bool canClose();
+
+ U32 getCategory();
+
+ void setCategory(U32 category);
+
+ U32 getContentType();
+
+ void setContentType(bool mature);
+
+ bool getAutoRenew();
+
+ S32 getPriceForListing() { return mPriceForListing; }
+
+ void setEditMode(BOOL edit_mode);
+ bool getEditMode() {return mEditMode;}
+
+ static void setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table);
+
+ static void sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name);
+
+ void doSave();
+
+protected:
+
+ void resetData() override;
+
+ void resetControls();
+
+ void updateButtons();
+ void updateInfoRect();
+
+ static std::string createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ void sendClickMessage(const std::string& type);
+
+ void scrollToTop();
+
+ void onEditClick();
+ void onCancelClick();
+ void onSaveClick();
+ void onMapClick();
+ void onTeleportClick();
+
+ void sendUpdate();
+
+ void enableSave(bool enable);
+
+ void enableEditing(bool enable);
+
+ std::string makeClassifiedName();
+
+ void setPriceForListing(S32 price) { mPriceForListing = price; }
+
+ U8 getFlags();
+
+ std::string getLocationNotice();
+
+ bool isValidName();
+
+ void notifyInvalidName();
+
+ void onSetLocationClick();
+ void onChange();
+
+ void onPublishFloaterPublishClicked();
+
+ void onTexturePickerMouseEnter();
+ void onTexturePickerMouseLeave();
+
+ void onTextureSelected();
+
+ void updateTabLabel(const std::string& title);
+
+private:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLUICtrl* mEditIcon;
+ LLUICtrl* mClassifiedNameText;
+ LLTextEditor* mClassifiedDescText;
+ LLLineEditor* mClassifiedNameEdit;
+ LLTextEditor* mClassifiedDescEdit;
+ LLUICtrl* mLocationText;
+ LLUICtrl* mLocationEdit;
+ LLUICtrl* mCategoryText;
+ LLComboBox* mCategoryCombo;
+ LLUICtrl* mContentTypeText;
+ LLIconCtrl* mContentTypeM;
+ LLIconCtrl* mContentTypeG;
+ LLComboBox* mContentTypeCombo;
+ LLUICtrl* mPriceText;
+ LLUICtrl* mAutoRenewText;
+ LLUICtrl* mAutoRenewEdit;
+
+ LLButton* mMapButton;
+ LLButton* mTeleportButton;
+ LLButton* mEditButton;
+ LLButton* mSaveButton;
+ LLButton* mSetLocationButton;
+ LLButton* mCancelButton;
+
+ LLPanel* mUtilityBtnCnt;
+ LLPanel* mPublishBtnsCnt;
+ LLPanel* mSaveBtnCnt;
+ LLPanel* mCancelBtnCnt;
+
+ LLScrollContainer* mScrollContainer;
+ LLView* mInfoPanel;
+ LLPanel* mInfoScroll;
+ LLPanel* mEditPanel;
+
+
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ std::string mSimName;
+ bool mFromSearch;
+ bool mInfoLoaded;
+ bool mEditMode;
+
+ // Needed for stat tracking
+ S32 mTeleportClicksOld;
+ S32 mMapClicksOld;
+ S32 mProfileClicksOld;
+ S32 mTeleportClicksNew;
+ S32 mMapClicksNew;
+ S32 mProfileClicksNew;
+
+ S32 mPriceForListing;
+
+ static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+ typedef std::list<LLPanelProfileClassified*> panel_list_t;
+ static panel_list_t sAllPanels;
+
+
+ bool mIsNew;
+ bool mIsNewWithErrors;
+ bool mCanClose;
+ bool mEditOnLoad;
+
+ LLPublishClassifiedFloater* mPublishFloater;
+};
+
+#endif // LL_PANELPROFILECLASSIFIEDS_H
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
new file mode 100644
index 0000000000..774119f169
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -0,0 +1,883 @@
+/**
+ * @file llpanelprofilepicks.cpp
+ * @brief LLPanelProfilePicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelprofilepicks.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcommandhandler.h"
+#include "lldispatcher.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
+
+
+class LLPickHandler : public LLCommandHandler
+{
+public:
+
+ // requires trusted browser to trigger
+ LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
+ {
+ LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/pick/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createPick();
+ return true;
+ }
+
+ // then handle the general app/pick/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the pick_id
+ LLUUID pick_id;
+ if (!pick_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // edit the pick in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "edit")
+ {
+ LLAvatarActions::showPick(gAgent.getID(), pick_id);
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "unknown verb " << verb << LL_ENDL;
+ return false;
+ }
+ }
+};
+LLPickHandler gPickHandler;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePicks
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePicks::LLPanelProfilePicks()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mPickToSelectOnLoad(LLUUID::null)
+{
+}
+
+LLPanelProfilePicks::~LLPanelProfilePicks()
+{
+}
+
+void LLPanelProfilePicks::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+}
+
+void LLPanelProfilePicks::createPick(const LLPickData &data)
+{
+ if (getIsLoaded())
+ {
+ if (canAddNewPick())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+ }
+ else
+ {
+ // This means that something doesn't properly check limits
+ // before creating a pick
+ LL_WARNS() << "failed to add pick" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mSheduledPickCreation.push_back(data);
+ }
+}
+
+void LLPanelProfilePicks::selectPick(const LLUUID& pick_id)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ if (pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->selectTabPanel(pick_panel);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mPickToSelectOnLoad = pick_id;
+ }
+}
+
+BOOL LLPanelProfilePicks::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_picks");
+ mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfilePicks::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+}
+
+void LLPanelProfilePicks::onClickDelete()
+{
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (pick_panel)
+ {
+ LLUUID pick_id = pick_panel->getPickId();
+ LLSD args;
+ args["PICK"] = pick_panel->getPickName();
+ LLSD payload;
+ payload["pick_id"] = pick_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeletePick", args, payload,
+ boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
+ }
+}
+
+void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID pick_id = notification["payload"]["pick_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->removeTabPanel(pick_panel);
+ }
+
+ if (pick_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id);
+ }
+
+ updateButtons();
+ }
+}
+
+void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if (avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ processProperties(avatar_picks);
+ }
+ }
+}
+
+void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
+{
+ LLUUID selected_id = mPickToSelectOnLoad;
+ bool has_selection = false;
+ if (mPickToSelectOnLoad.isNull())
+ {
+ if (mTabContainer->getTabCount() > 0)
+ {
+ LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (active_pick_panel)
+ {
+ selected_id = active_pick_panel->getPickId();
+ }
+ }
+ }
+
+ mTabContainer->deleteAllTabs();
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for (; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+
+ pick_panel->setPickId(pick_id);
+ pick_panel->setPickName(pick_name);
+ pick_panel->setAvatarId(getAvatarId());
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(selected_id == pick_id).
+ label(pick_name));
+
+ if (selected_id == pick_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ while (!mSheduledPickCreation.empty() && canAddNewPick())
+ {
+ const LLPickData data =
+ mSheduledPickCreation.back();
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(!has_selection).
+ label(pick_panel->getPickName()));
+
+ mSheduledPickCreation.pop_back();
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mPickToSelectOnLoad = LLUUID::null;
+ mSheduledPickCreation.clear();
+
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+}
+
+void LLPanelProfilePicks::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfilePicks::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewPick());
+ mDeleteButton->setEnabled(canDeletePick());
+ }
+}
+
+void LLPanelProfilePicks::apply()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+ }
+}
+
+void LLPanelProfilePicks::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
+ }
+ if (!getIsLoaded())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+ }
+}
+
+bool LLPanelProfilePicks::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLPanelProfilePicks::commitUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+}
+
+bool LLPanelProfilePicks::canAddNewPick()
+{
+ return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
+ mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks());
+}
+
+bool LLPanelProfilePicks::canDeletePick()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePick
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePick::LLPanelProfilePick()
+ : LLPanelProfilePropertiesProcessorTab()
+ , LLRemoteParcelInfoObserver()
+ , mSnapshotCtrl(NULL)
+ , mPickId(LLUUID::null)
+ , mParcelId(LLUUID::null)
+ , mRequestedId(LLUUID::null)
+ , mLocationChanged(false)
+ , mNewPick(false)
+ , mIsEditing(false)
+{
+}
+
+//static
+LLPanelProfilePick* LLPanelProfilePick::create()
+{
+ LLPanelProfilePick* panel = new LLPanelProfilePick();
+ panel->buildFromFile("panel_profile_pick.xml");
+ return panel;
+}
+
+LLPanelProfilePick::~LLPanelProfilePick()
+{
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ // creating new Pick
+ if (getPickId().isNull() && getSelfProfile())
+ {
+ mNewPick = true;
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
+ std::string pick_name, pick_desc, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ parcel_id = parcel->getID();
+ pick_name = parcel->getName();
+ pick_desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setParcelID(parcel_id);
+ setPickName(pick_name.empty() ? region_name : pick_name);
+ setPickDesc(pick_desc);
+ setSnapshotId(snapshot_id);
+ setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
+
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+
+ enableSaveButton(FALSE);
+ }
+
+ resetDirty();
+
+ if (getSelfProfile())
+ {
+ mPickName->setEnabled(TRUE);
+ mPickDescription->setEnabled(TRUE);
+ mSetCurrentLocationButton->setVisible(TRUE);
+ }
+ else
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+}
+
+BOOL LLPanelProfilePick::postBuild()
+{
+ mPickName = getChild<LLLineEditor>("pick_name");
+ mPickDescription = getChild<LLTextEditor>("pick_desc");
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mCreateButton = getChild<LLButton>("create_changes_btn");
+ mCancelButton = getChild<LLButton>("cancel_changes_btn");
+ mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
+ mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this));
+
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
+ mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
+
+ mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
+ mPickName->setEnabled(FALSE);
+
+ mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1));
+ mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this));
+
+ getChild<LLUICtrl>("pick_location")->setEnabled(FALSE);
+
+ return TRUE;
+}
+
+void LLPanelProfilePick::onDescriptionFocusReceived()
+{
+ if (!mIsEditing && getSelfProfile())
+ {
+ mIsEditing = true;
+ mPickDescription->setParseHTML(false);
+ }
+}
+
+void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type)
+ {
+ return;
+ }
+
+ LLPickData* pick_info = static_cast<LLPickData*>(data);
+ if (!pick_info
+ || pick_info->creator_id != getAvatarId()
+ || pick_info->pick_id != getPickId())
+ {
+ return;
+ }
+
+ processProperties(pick_info);
+}
+
+void LLPanelProfilePick::processProperties(const LLPickData* pick_info)
+{
+ mIsEditing = false;
+ mPickDescription->setParseHTML(true);
+ mParcelId = pick_info->parcel_id;
+ setSnapshotId(pick_info->snapshot_id);
+ if (!getSelfProfile())
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+ setPickName(pick_info->name);
+ setPickDesc(pick_info->desc);
+ setPosGlobal(pick_info->pos_global);
+
+ // Send remote parcel info request to get parcel name and sim (region) name.
+ sendParcelInfoRequest();
+
+ // *NOTE dzaporozhan
+ // We want to keep listening to APT_PICK_INFO because user may
+ // edit the Pick and we have to update Pick info panel.
+ // revomeObserver is called from onClickBack
+
+ setLoaded();
+}
+
+void LLPanelProfilePick::apply()
+{
+ if ((mNewPick || getIsLoaded()) && isDirty())
+ {
+ sendUpdate();
+ }
+}
+
+void LLPanelProfilePick::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setImageAssetID(id);
+ mSnapshotCtrl->setValid(TRUE);
+}
+
+void LLPanelProfilePick::setPickName(const std::string& name)
+{
+ mPickName->setValue(name);
+}
+
+const std::string LLPanelProfilePick::getPickName()
+{
+ return mPickName->getValue().asString();
+}
+
+void LLPanelProfilePick::setPickDesc(const std::string& desc)
+{
+ mPickDescription->setValue(desc);
+}
+
+void LLPanelProfilePick::setPickLocation(const std::string& location)
+{
+ getChild<LLUICtrl>("pick_location")->setValue(location);
+}
+
+void LLPanelProfilePick::onClickMap()
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfilePick::onClickTeleport()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+void LLPanelProfilePick::enableSaveButton(BOOL enable)
+{
+ childSetVisible("save_changes_lp", enable);
+
+ childSetVisible("save_btn_lp", enable && !mNewPick);
+ childSetVisible("create_btn_lp", enable && mNewPick);
+ childSetVisible("cancel_btn_lp", enable && !mNewPick);
+}
+
+void LLPanelProfilePick::onSnapshotChanged()
+{
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl)
+{
+ if (ctrl && ctrl == mPickName)
+ {
+ updateTabLabel(mPickName->getText());
+ }
+
+ enableSaveButton(isDirty());
+}
+
+void LLPanelProfilePick::resetDirty()
+{
+ LLPanel::resetDirty();
+
+ mPickName->resetDirty();
+ mPickDescription->resetDirty();
+ mSnapshotCtrl->resetDirty();
+ mLocationChanged = false;
+}
+
+BOOL LLPanelProfilePick::isDirty() const
+{
+ if (mNewPick
+ || LLPanel::isDirty()
+ || mLocationChanged
+ || mSnapshotCtrl->isDirty()
+ || mPickName->isDirty()
+ || mPickDescription->isDirty())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLPanelProfilePick::onClickSetLocation()
+{
+ // Save location for later use.
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ std::string parcel_name, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mParcelId = parcel->getID();
+ parcel_name = parcel->getName();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onClickSave()
+{
+ sendUpdate();
+
+ mLocationChanged = false;
+}
+
+void LLPanelProfilePick::onClickCancel()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+ mLocationChanged = false;
+ enableSaveButton(FALSE);
+}
+
+std::string LLPanelProfilePick::getLocationNotice()
+{
+ static const std::string notice = getString("location_notice");
+ return notice;
+}
+
+void LLPanelProfilePick::sendParcelInfoRequest()
+{
+ if (mParcelId != mRequestedId)
+ {
+ if (mRequestedId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
+ }
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
+
+ mRequestedId = mParcelId;
+ }
+}
+
+void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
+{
+ setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
+
+ // We have received parcel info for the requested ID so clear it now.
+ mRequestedId.setNull();
+
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::sendUpdate()
+{
+ LLPickData pick_data;
+
+ // If we don't have a pick id yet, we'll need to generate one,
+ // otherwise we'll keep overwriting pick_id 00000 in the database.
+ if (getPickId().isNull())
+ {
+ getPickId().generate();
+ }
+
+ pick_data.agent_id = gAgentID;
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = getPickId();
+ pick_data.creator_id = gAgentID;;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelId;
+ pick_data.name = getPickName();
+ pick_data.desc = mPickDescription->getValue().asString();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = getPosGlobal();
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
+
+ if(mNewPick)
+ {
+ // Assume a successful create pick operation, make new number of picks
+ // available immediately. Actual number of picks will be requested in
+ // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+ LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+ }
+}
+
+// static
+std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
+{
+ std::string location_text(owner_name);
+ if (!original_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(original_name);
+
+ }
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ {
+ location_text.append(" ");
+ }
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+ return location_text;
+}
+
+void LLPanelProfilePick::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h
new file mode 100644
index 0000000000..f84463cc9b
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.h
@@ -0,0 +1,248 @@
+/**
+ * @file llpanelprofilepicks.h
+ * @brief LLPanelProfilePicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPICKS_H
+#define LL_LLPANELPICKS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llremoteparcelrequest.h"
+
+class LLTabContainer;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLLineEditor;
+class LLTextEditor;
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfilePicks
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfilePicks();
+ /*virtual*/ ~LLPanelProfilePicks();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void selectPick(const LLUUID& pick_id);
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLAvatarPicks* avatar_picks);
+
+ void resetData() override;
+
+ void updateButtons();
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeletePick(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewPick();
+ bool canDeletePick();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mPickToSelectOnLoad;
+ std::list<LLPickData> mSheduledPickCreation;
+};
+
+
+class LLPanelProfilePick
+ : public LLPanelProfilePropertiesProcessorTab
+ , public LLRemoteParcelInfoObserver
+{
+public:
+
+ // Creates new panel
+ static LLPanelProfilePick* create();
+
+ LLPanelProfilePick();
+
+ /*virtual*/ ~LLPanelProfilePick();
+
+ BOOL postBuild() override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ void setPickId(const LLUUID& id) { mPickId = id; }
+ virtual LLUUID& getPickId() { return mPickId; }
+
+ virtual void setPickName(const std::string& name);
+ const std::string getPickName();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLPickData* pick_data);
+
+ /**
+ * Returns true if any of Pick properties was changed by user.
+ */
+ BOOL isDirty() const override;
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ void updateTabLabel(const std::string& title);
+
+ //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
+ void processParcelInfo(const LLParcelData& parcel_data) override;
+ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
+ void setErrorStatus(S32 status, const std::string& reason) override {};
+
+protected:
+
+ /**
+ * Sends remote parcel info request to resolve parcel name from its ID.
+ */
+ void sendParcelInfoRequest();
+
+ /**
+ * "Location text" is actually the owner name, the original
+ * name that owner gave the parcel, and the location.
+ */
+ static std::string createLocationText(
+ const std::string& owner_name,
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ /**
+ * Sets snapshot id.
+ *
+ * Will mark snapshot control as valid if id is not null.
+ * Will mark snapshot control as invalid if id is null. If null id is a valid value,
+ * you have to manually mark snapshot is valid.
+ */
+ virtual void setSnapshotId(const LLUUID& id);
+ virtual void setPickDesc(const std::string& desc);
+ virtual void setPickLocation(const std::string& location);
+
+ virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+ virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ /**
+ * Callback for "Map" button, opens Map
+ */
+ void onClickMap();
+
+ /**
+ * Callback for "Teleport" button, teleports user to Pick location.
+ */
+ void onClickTeleport();
+
+ /**
+ * Enables/disables "Save" button
+ */
+ void enableSaveButton(BOOL enable);
+
+ /**
+ * Called when snapshot image changes.
+ */
+ void onSnapshotChanged();
+
+ /**
+ * Callback for Pick snapshot, name and description changed event.
+ */
+ void onPickChanged(LLUICtrl* ctrl);
+
+ /**
+ * Resets panel and all cantrols to unedited state
+ */
+ void resetDirty() override;
+
+ /**
+ * Callback for "Set Location" button click
+ */
+ void onClickSetLocation();
+
+ /**
+ * Callback for "Save" and "Create" button click
+ */
+ void onClickSave();
+
+ /**
+ * Callback for "Save" button click
+ */
+ void onClickCancel();
+
+ std::string getLocationNotice();
+
+ /**
+ * Sends Pick properties to server.
+ */
+ void sendUpdate();
+
+protected:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLLineEditor* mPickName;
+ LLTextEditor* mPickDescription;
+ LLButton* mSetCurrentLocationButton;
+ LLButton* mSaveButton;
+ LLButton* mCreateButton;
+ LLButton* mCancelButton;
+
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ LLUUID mPickId;
+ LLUUID mRequestedId;
+
+ bool mLocationChanged;
+ bool mNewPick;
+ bool mIsEditing;
+
+ void onDescriptionFocusReceived();
+};
+
+#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 89c558e4f8..db37938448 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -51,6 +51,7 @@
#include "llfocusmgr.h"
#include "llmanipscale.h"
#include "llinventorymodel.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -145,6 +146,15 @@ BOOL LLPanelVolume::postBuild()
getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
}
+ // REFLECTION PROBE Parameters
+ {
+ childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
+ childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
+ childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
+ childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
+ childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
+ }
+
// PHYSICS Parameters
{
// PhysicsShapeType combobox
@@ -168,6 +178,9 @@ BOOL LLPanelVolume::postBuild()
mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution));
}
+ mMenuClipboardFeatures = getChild<LLMenuButton>("clipboard_features_params_btn");
+ mMenuClipboardLight = getChild<LLMenuButton>("clipboard_light_params_btn");
+
std::map<std::string, std::string> material_name_map;
material_name_map["Stone"]= LLTrans::getString("Stone");
material_name_map["Metal"]= LLTrans::getString("Metal");
@@ -208,6 +221,8 @@ LLPanelVolume::LLPanelVolume()
{
setMouseOpaque(FALSE);
+ mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2));
}
@@ -360,6 +375,43 @@ void LLPanelVolume::getState( )
getChildView("Light Ambiance")->setEnabled(false);
}
+ // Reflection Probe
+ BOOL is_probe = volobjp && volobjp->isReflectionProbe();
+ getChild<LLUICtrl>("Reflection Probe")->setValue(is_probe);
+ getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp);
+
+ bool probe_enabled = is_probe && editable && single_volume;
+
+ getChildView("Probe Dynamic")->setEnabled(probe_enabled);
+ getChildView("Probe Volume Type")->setEnabled(probe_enabled);
+ getChildView("Probe Ambiance")->setEnabled(probe_enabled);
+ getChildView("Probe Near Clip")->setEnabled(probe_enabled);
+
+ if (!probe_enabled)
+ {
+ getChild<LLComboBox>("Probe Volume Type", true)->clear();
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
+ }
+ else
+ {
+ std::string volume_type;
+ if (volobjp->getReflectionProbeIsBox())
+ {
+ volume_type = "Box";
+ }
+ else
+ {
+ volume_type = "Sphere";
+ }
+
+ getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
+ }
+
// Animated Mesh
BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
@@ -409,7 +461,6 @@ void LLPanelVolume::getState( )
gAgentAvatarp->updateMeshVisibility();
}
}
-
// Flexible properties
BOOL is_flexible = volobjp && volobjp->isFlexible();
@@ -564,6 +615,9 @@ void LLPanelVolume::getState( )
mObject = objectp;
mRootObject = root_objectp;
+
+ mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume
+ mMenuClipboardLight->setEnabled(editable && single_volume && volobjp);
}
// static
@@ -587,13 +641,6 @@ void LLPanelVolume::refresh()
mRootObject = NULL;
}
- BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
-
- getChildView("Light FOV")->setVisible( visible);
- getChildView("Light Focus")->setVisible( visible);
- getChildView("Light Ambiance")->setVisible( visible);
- getChildView("light texture control")->setVisible( visible);
-
bool enable_mesh = false;
LLSD sim_features;
@@ -647,6 +694,11 @@ void LLPanelVolume::clearCtrls()
getChildView("Light Radius")->setEnabled(false);
getChildView("Light Falloff")->setEnabled(false);
+ getChildView("Reflection Probe")->setEnabled(false);;
+ getChildView("Probe Volume Type")->setEnabled(false);
+ getChildView("Probe Dynamic")->setEnabled(false);
+ getChildView("Probe Ambiance")->setEnabled(false);
+ getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
getChildView("FlexNumSections")->setEnabled(false);
@@ -684,6 +736,20 @@ void LLPanelVolume::sendIsLight()
LL_INFOS() << "update light sent" << LL_ENDL;
}
+void LLPanelVolume::sendIsReflectionProbe()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
+ volobjp->setIsReflectionProbe(value);
+ LL_INFOS() << "update reflection probe sent" << LL_ENDL;
+}
+
void LLPanelVolume::sendIsFlexible()
{
LLViewerObject* objectp = mObject;
@@ -831,6 +897,311 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data)
}
}
+void LLPanelVolume::onCopyFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Flexi Prim
+ if (volobjp && volobjp->isFlexible())
+ {
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ clipboard["flex"]["lod"] = attributes->getSimulateLOD();
+ clipboard["flex"]["gav"] = attributes->getGravity();
+ clipboard["flex"]["ten"] = attributes->getTension();
+ clipboard["flex"]["fri"] = attributes->getAirFriction();
+ clipboard["flex"]["sen"] = attributes->getWindSensitivity();
+ LLVector3 force = attributes->getUserForce();
+ clipboard["flex"]["forx"] = force.mV[0];
+ clipboard["flex"]["fory"] = force.mV[1];
+ clipboard["flex"]["forz"] = force.mV[2];
+ }
+ }
+
+ // Physics
+ {
+ clipboard["physics"]["shape"] = objectp->getPhysicsShapeType();
+ clipboard["physics"]["gravity"] = objectp->getPhysicsGravity();
+ clipboard["physics"]["friction"] = objectp->getPhysicsFriction();
+ clipboard["physics"]["density"] = objectp->getPhysicsDensity();
+ clipboard["physics"]["restitution"] = objectp->getPhysicsRestitution();
+
+ U8 material_code = 0;
+ struct f : public LLSelectedTEGetFunctor<U8>
+ {
+ U8 get(LLViewerObject* object, S32 te)
+ {
+ return object->getMaterial();
+ }
+ } func;
+ bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, material_code);
+ // This should always be true since material should be per object.
+ if (material_same)
+ {
+ clipboard["physics"]["material"] = material_code;
+ }
+ }
+
+ mClipboardParams["features"] = clipboard;
+}
+
+void LLPanelVolume::onPasteFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("features"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["features"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Physics
+ bool is_root = objectp->isRoot();
+
+ // Not sure if phantom should go under physics, but doesn't fit elsewhere
+ BOOL is_phantom = clipboard["is_phantom"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom);
+
+ BOOL is_physical = clipboard["is_physical"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical);
+
+ if (clipboard.has("physics"))
+ {
+ objectp->setPhysicsShapeType((U8)clipboard["physics"]["shape"].asInteger());
+ U8 cur_material = objectp->getMaterial();
+ U8 material = (U8)clipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK);
+
+ objectp->setMaterial(material);
+ objectp->sendMaterialUpdate();
+ objectp->setPhysicsGravity(clipboard["physics"]["gravity"].asReal());
+ objectp->setPhysicsFriction(clipboard["physics"]["friction"].asReal());
+ objectp->setPhysicsDensity(clipboard["physics"]["density"].asReal());
+ objectp->setPhysicsRestitution(clipboard["physics"]["restitution"].asReal());
+ objectp->updateFlags(TRUE);
+ }
+
+ // Flexible
+ bool is_flexible = clipboard.has("flex");
+ if (is_flexible && volobjp->canBeFlexible())
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ BOOL update_shape = FALSE;
+
+ // do before setParameterEntry or it will think that it is already flexi
+ update_shape = volobjp->setIsFlexible(is_flexible);
+
+ if (objectp->getClickAction() == CLICK_ACTION_SIT)
+ {
+ objectp->setClickAction(CLICK_ACTION_NONE);
+ }
+
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ LLFlexibleObjectData new_attributes;
+ new_attributes = *attributes;
+ new_attributes.setSimulateLOD(clipboard["flex"]["lod"].asInteger());
+ new_attributes.setGravity(clipboard["flex"]["gav"].asReal());
+ new_attributes.setTension(clipboard["flex"]["ten"].asReal());
+ new_attributes.setAirFriction(clipboard["flex"]["fri"].asReal());
+ new_attributes.setWindSensitivity(clipboard["flex"]["sen"].asReal());
+ F32 fx = (F32)clipboard["flex"]["forx"].asReal();
+ F32 fy = (F32)clipboard["flex"]["fory"].asReal();
+ F32 fz = (F32)clipboard["flex"]["forz"].asReal();
+ LLVector3 force(fx, fy, fz);
+ new_attributes.setUserForce(force);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
+ }
+
+ if (update_shape)
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+ else
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->setIsFlexible(false))
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+}
+
+void LLPanelVolume::onCopyLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp && volobjp->getIsLight())
+ {
+ clipboard["light"]["intensity"] = volobjp->getLightIntensity();
+ clipboard["light"]["radius"] = volobjp->getLightRadius();
+ clipboard["light"]["falloff"] = volobjp->getLightFalloff();
+ LLColor3 color = volobjp->getLightSRGBColor();
+ clipboard["light"]["r"] = color.mV[0];
+ clipboard["light"]["g"] = color.mV[1];
+ clipboard["light"]["b"] = color.mV[2];
+
+ // Spotlight
+ if (volobjp->isLightSpotlight())
+ {
+ LLUUID id = volobjp->getLightTextureID();
+ if (id.notNull() && get_can_copy_texture(id))
+ {
+ clipboard["spot"]["id"] = id;
+ LLVector3 spot_params = volobjp->getSpotLightParams();
+ clipboard["spot"]["fov"] = spot_params.mV[0];
+ clipboard["spot"]["focus"] = spot_params.mV[1];
+ clipboard["spot"]["ambiance"] = spot_params.mV[2];
+ }
+ }
+ }
+
+ if (volobjp && volobjp->isReflectionProbe())
+ {
+ clipboard["reflection_probe"]["is_box"] = volobjp->getReflectionProbeIsBox();
+ clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
+ clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
+ clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
+ }
+
+ mClipboardParams["light"] = clipboard;
+}
+
+void LLPanelVolume::onPasteLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("light"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["light"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp)
+ {
+ if (clipboard.has("light"))
+ {
+ volobjp->setIsLight(TRUE);
+ volobjp->setLightIntensity((F32)clipboard["light"]["intensity"].asReal());
+ volobjp->setLightRadius((F32)clipboard["light"]["radius"].asReal());
+ volobjp->setLightFalloff((F32)clipboard["light"]["falloff"].asReal());
+ F32 r = (F32)clipboard["light"]["r"].asReal();
+ F32 g = (F32)clipboard["light"]["g"].asReal();
+ F32 b = (F32)clipboard["light"]["b"].asReal();
+ volobjp->setLightSRGBColor(LLColor3(r, g, b));
+ }
+ else
+ {
+ volobjp->setIsLight(FALSE);
+ }
+
+ if (clipboard.has("spot"))
+ {
+ volobjp->setLightTextureID(clipboard["spot"]["id"].asUUID());
+ LLVector3 spot_params;
+ spot_params.mV[0] = (F32)clipboard["spot"]["fov"].asReal();
+ spot_params.mV[1] = (F32)clipboard["spot"]["focus"].asReal();
+ spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal();
+ volobjp->setSpotLightParams(spot_params);
+ }
+
+ if (clipboard.has("reflection_probe"))
+ {
+ volobjp->setIsReflectionProbe(TRUE);
+ volobjp->setReflectionProbeIsBox(clipboard["reflection_probe"]["is_box"].asBoolean());
+ volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
+ volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
+ volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
+ }
+ else
+ {
+ volobjp->setIsReflectionProbe(false);
+ }
+ }
+}
+
+void LLPanelVolume::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "features_paste")
+ {
+ onPasteFeatures();
+ }
+ else if (command == "light_paste")
+ {
+ onPasteLight();
+ }
+ // copy
+ else if (command == "features_copy")
+ {
+ onCopyFeatures();
+ }
+ else if (command == "light_copy")
+ {
+ onCopyLight();
+ }
+}
+
+bool LLPanelVolume::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "features_paste")
+ {
+ return mClipboardParams.has("features");
+ }
+ else if (command == "light_paste")
+ {
+ return mClipboardParams.has("light");
+ }
+ return false;
+}
+
// static
void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
@@ -927,6 +1298,27 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
}
+//static
+void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+
+ volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
+ volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
+ volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
+
+ std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
+
+ volobjp->setReflectionProbeIsBox(shape_type == "Box");
+}
+
// static
void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
{
@@ -942,7 +1334,7 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
LLViewerInventoryItem* item = gInventory.getItem(item_id);
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- LLToolDragAndDrop::handleDropTextureProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
volobjp->setLightTextureID(asset_id);
}
@@ -950,6 +1342,15 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
//----------------------------------------------------------------------------
// static
+void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ self->sendIsReflectionProbe();
+}
+
+//----------------------------------------------------------------------------
+
+// static
void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
{
LLPanelVolume* self = (LLPanelVolume*) userdata;
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 6e49ccb742..62a6d01b21 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -56,12 +57,15 @@ public:
void refresh();
void sendIsLight();
+ void sendIsReflectionProbe();
void sendIsFlexible();
static bool precommitValidate(const LLSD& data);
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
+ static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata);
+ static void onCommitProbe(LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
@@ -76,6 +80,13 @@ public:
static void setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp);
+ void onCopyFeatures();
+ void onPasteFeatures();
+ void onCopyLight();
+ void onPasteLight();
+
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
protected:
void getState();
@@ -123,6 +134,11 @@ protected:
LLSpinCtrl* mSpinPhysicsFriction;
LLSpinCtrl* mSpinPhysicsDensity;
LLSpinCtrl* mSpinPhysicsRestitution;
+
+ LLMenuButton* mMenuClipboardFeatures;
+ LLMenuButton* mMenuClipboardLight;
+
+ LLSD mClipboardParams;
};
#endif
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 94d20828ec..9b60d1ae2f 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -38,154 +38,11 @@
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
-// See EXT-4301.
-/**
- * class LLAvalineUpdater - observe the list of voice participants in session and check
- * presence of Avaline Callers among them.
- *
- * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation:
- * - whether Avaline caller presence among participants;
- * - whether watched Avaline caller still exists in voice channel.
- * Both validations have callbacks which will notify subscriber if any of event occur.
- *
- * @see findAvalineCaller()
- * @see checkIfAvalineCallersExist()
- */
-class LLAvalineUpdater : public LLVoiceClientParticipantObserver
-{
-public:
- typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t;
-
- LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb)
- : mAvalineFoundCallback(found_cb)
- , mAvalineRemovedCallback(removed_cb)
- {
- LLVoiceClient::getInstance()->addObserver(this);
- }
- ~LLAvalineUpdater()
- {
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
- }
-
- /**
- * Adds UUID of Avaline caller to watch.
- *
- * @see checkIfAvalineCallersExist().
- */
- void watchAvalineCaller(const LLUUID& avaline_caller_id)
- {
- mAvalineCallers.insert(avaline_caller_id);
- }
-
- void onParticipantsChanged()
- {
- uuid_set_t participant_uuids;
- LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
-
-
- // check whether Avaline caller exists among voice participants
- // and notify Participant List
- findAvalineCaller(participant_uuids);
-
- // check whether watched Avaline callers still present among voice participant
- // and remove if absents.
- checkIfAvalineCallersExist(participant_uuids);
- }
-
-private:
- typedef std::set<LLUUID> uuid_set_t;
-
- /**
- * Finds Avaline callers among voice participants and calls mAvalineFoundCallback.
- *
- * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays
- * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again
- * Avaline caller is added to voice channel AFTER Avatar is connected to group call.
- * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information
- * if a speaker is Avaline caller.
- *
- * In this case this speaker is created as avatar and will be recreated when it appears in
- * Avatar's Voice session.
- *
- * @see LLParticipantList::onAvalineCallerFound()
- */
- void findAvalineCaller(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end();
-
- for(; it != it_end; ++it)
- {
- const LLUUID& participant_id = *it;
- if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id))
- {
- LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL;
-
- if (mAvalineFoundCallback)
- {
- mAvalineFoundCallback(participant_id);
- }
- }
- }
- }
-
- /**
- * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback.
- *
- * The problem is when Avaline caller ends a call it is removed from Voice Client session but
- * still exists in LLSpeakerMgr. Server does not send such information.
- * This method implements a HUCK to notify subscribers that watched Avaline callers by class
- * are not anymore in the call.
- *
- * @see LLParticipantList::onAvalineCallerRemoved()
- */
- void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::iterator it = mAvalineCallers.begin();
- uuid_set_t::const_iterator participants_it_end = participant_uuids.end();
-
- while (it != mAvalineCallers.end())
- {
- const LLUUID participant_id = *it;
- LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL;
- bool not_found = participant_uuids.find(participant_id) == participants_it_end;
- if (not_found)
- {
- LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL;
-
- // notify Participant List
- if (mAvalineRemovedCallback)
- {
- mAvalineRemovedCallback(participant_id);
- }
-
- // remove from the watch list
- mAvalineCallers.erase(it++);
- }
- else
- {
- ++it;
- }
- }
- }
-
- process_avaline_callback_t mAvalineFoundCallback;
- process_avaline_callback_t mAvalineRemovedCallback;
-
- uuid_set_t mAvalineCallers;
-};
-
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
LLConversationItemSession(data_source->getSessionID(), root_view_model),
mSpeakerMgr(data_source),
mValidateSpeakerCallback(NULL)
{
-
- mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1),
- boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1));
-
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
@@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode
LLParticipantList::~LLParticipantList()
{
- delete mAvalineUpdater;
-}
-
-/*
- Seems this method is not necessary after onAvalineCallerRemoved was implemented;
-
- It does nothing because list item is always created with correct class type for Avaline caller.
- For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client
- session.
- This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call.
-
- Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself.
- Asked in EXT-4301.
-*/
-void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
-{
- removeParticipant(participant_id);
- // re-add avaline caller with a correct class instance.
- addAvatarIDExceptAgent(participant_id);
-}
-
-void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
-{
- LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL;
-
- mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
@@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
// Create a participant view model instance
participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
- mAvalineUpdater->watchAvalineCaller(avatar_id);
}
// *TODO : Need to update the online/offline status of the participant
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 3a3ae76604..14c0a63692 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -32,7 +32,6 @@
class LLSpeakerMgr;
class LLUICtrl;
-class LLAvalineUpdater;
class LLParticipantList : public LLConversationItemSession
{
@@ -133,8 +132,6 @@ protected:
};
private:
- void onAvalineCallerFound(const LLUUID& participant_id);
- void onAvalineCallerRemoved(const LLUUID& participant_id);
/**
* Adjusts passed participant to work properly.
@@ -156,7 +153,6 @@ private:
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
validate_speaker_callback_t mValidateSpeakerCallback;
- LLAvalineUpdater* mAvalineUpdater;
};
#endif // LL_PARTICIPANTLIST_H
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 6e3e375488..a7011dfad5 100644
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
// (The -1 is there because an LLSurface has a buffer of 1 on
// its East and North edges).
U32 power_of_two = 1;
- U32 surface_order = 0;
while (power_of_two < (surface_width-1))
{
power_of_two *= 2;
- surface_order += 1;
}
if (power_of_two == (surface_width-1))
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 852b39f442..17b8ec0683 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -61,7 +61,8 @@
#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
-#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects"
+#define CAP_SERVICE_GET_OBJECT_LINKSETS "RegionObjects"
+#define CAP_SERVICE_SET_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
#define CAP_SERVICE_CHARACTERS "CharacterProperties"
@@ -244,7 +245,7 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
}
else
{
- std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string objectLinksetsURL = getRetrieveObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@@ -273,7 +274,7 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
{
LLPathfindingObjectListPtr emptyLinksetListPtr;
- std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string objectLinksetsURL = getChangeObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@@ -755,9 +756,14 @@ std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion
return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH);
}
-std::string LLPathfindingManager::getObjectLinksetsURLForCurrentRegion() const
+std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() const
{
- return getCapabilityURLForCurrentRegion(CAP_SERVICE_OBJECT_LINKSETS);
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_GET_OBJECT_LINKSETS);
+}
+
+std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS);
}
std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index a44cd892da..bb44f780c8 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -122,7 +122,8 @@ private:
std::string getNavMeshStatusURLForCurrentRegion() const;
std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const;
std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const;
- std::string getObjectLinksetsURLForCurrentRegion() const;
+ std::string getRetrieveObjectLinksetsURLForCurrentRegion() const;
+ std::string getChangeObjectLinksetsURLForCurrentRegion() const;
std::string getTerrainLinksetsURLForCurrentRegion() const;
std::string getCharactersURLForCurrentRegion() const;
std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const;
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9bc77393dc..9bf771db8a 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications()
LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
-void LLPersistentNotificationStorage::initialize()
+void LLPersistentNotificationStorage::reset()
{
- std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
- setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+ std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
+ setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+}
+void LLPersistentNotificationStorage::initialize()
+{
+ reset();
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
}
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index 1fb4487286..335d85aaf6 100644
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -52,6 +52,7 @@ public:
void saveNotifications();
void loadNotifications();
+ void reset();
protected:
diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp
index 5bfe5c9941..9603ee6329 100644
--- a/indra/newview/llphysicsshapebuilderutil.cpp
+++ b/indra/newview/llphysicsshapebuilderutil.cpp
@@ -29,7 +29,7 @@
#include "llphysicsshapebuilderutil.h"
/* static */
-void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut )
+void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)
{
const LLProfileParams& profile_params = volume_params.getProfileParams();
const LLPathParams& path_params = volume_params.getPathParams();
@@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
if ( volume_params.shouldForceConvex() )
{
+ // Server distinguishes between convex of a prim vs isSculpt, but we don't care.
specOut.mType = PhysicsShapeSpecification::USER_CONVEX;
}
// Make a simpler convex shape if we can.
@@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
{
specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
}
+ else if (volume_params.isMeshSculpt() &&
+ // Check overall dimensions, not individual triangles.
+ (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE
+ ) )
+ {
+ // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't.
+ specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
+ }
else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy)
{
specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT;
diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h
index bd5b7d799c..b3b100296f 100644
--- a/indra/newview/llphysicsshapebuilderutil.h
+++ b/indra/newview/llphysicsshapebuilderutil.h
@@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f;
const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f;
const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE;
const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE;
+const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f;
class LLPhysicsVolumeParams : public LLVolumeParams
{
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 5629438415..3c27964ec5 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -40,7 +40,7 @@ public:
{
Params()
{
- filter_asset_type = "landmark";
+ filter_asset_types = "landmark";
}
};
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index c267c3c699..30d0a22ef0 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -332,7 +332,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
else
{
ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
- bool new_camera_offsets = false;
if (IS_CAMERA)
{
if (isDefaultCameraPreset(name))
@@ -354,7 +353,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
{
new_camera_preset = CAMERA_PRESET_CUSTOM;
}
- new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset);
}
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
{
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index 9ac15d1639..ab60f4c008 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -83,7 +83,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual void onOpen(const LLSD& key);
- void setAuxItem( const LLInventoryItem* item );
+ virtual void setAuxItem( const LLInventoryItem* item );
static void onBtnCopyToInv(void* userdata);
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 39cdb6fb04..759e7859f2 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -347,9 +347,6 @@ BOOL LLPreviewGesture::postBuild()
LLTextBox* text;
LLCheckBoxCtrl* check;
- edit = getChild<LLLineEditor>("name");
- edit->setKeystrokeCallback(onKeystrokeCommit, this);
-
edit = getChild<LLLineEditor>("desc");
edit->setKeystrokeCallback(onKeystrokeCommit, this);
@@ -482,9 +479,6 @@ BOOL LLPreviewGesture::postBuild()
{
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
getChild<LLLineEditor>("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
-
- getChild<LLUICtrl>("name")->setValue(item->getName());
- getChild<LLLineEditor>("name")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
}
return LLPreview::postBuild();
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 230def5362..3fd4f51559 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index a32dc8beda..5043250e08 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
@@ -1199,7 +1202,7 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
void LLScriptEdCore::onBtnLoadFromFile( void* data )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false);
}
void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data)
@@ -1240,7 +1243,7 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata )
if( self->mSaveCallback )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName);
}
}
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index cd7b93aba7..975e2bb910 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -296,7 +296,7 @@ void LLPreviewTexture::saveAs()
return;
std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null;
- (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename);
}
void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames)
@@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
// add space for dimensions and aspect ratio
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
-
+ if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
+ {
+ info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
+ }
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
@@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()
mPreviewToSave = TRUE;
}
+void LLPreviewTexture::hideCtrlButtons()
+{
+ getChildView("desc txt")->setVisible(false);
+ getChildView("desc")->setVisible(false);
+ getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true);
+ getChild<LLLayoutPanel>("buttons_panel")->setVisible(false);
+ getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained
+ reshape(getRect().getWidth(), getRect().getHeight());
+}
+
// static
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
LLViewerFetchedTexture *src_vi,
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 9b6a843875..16db51332e 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -67,6 +67,8 @@ public:
static void onSaveAsBtn(void* data);
+ void hideCtrlButtons();
+
/*virtual*/ void setObjectID(const LLUUID& object_id);
protected:
void init();
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 83b0c4f1bf..0faf6bf889 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)
if (is_not_group_id)
{
- // For each avaline call the id of caller is different even if
- // the phone number is the same.
- // To avoid duplication of avaline list items in the recent list
- // of panel People, deleting id's with similar phone number.
- const LLUUID& caller_id = getIDByPhoneNumber(userdata);
- if (caller_id.notNull())
- mPeople.erase(caller_id);
-
//[] instead of insert to replace existing id->llsd["date"] with new date value
mPeople[id] = userdata;
mChangedSignal();
@@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const
return no_data;
}
-bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const
-{
- recent_people_t::const_iterator it = mPeople.find(id);
-
- if (it != mPeople.end())
- {
- const LLSD& user = it->second;
- return user["avaline_call"].asBoolean();
- }
-
- return false;
-}
-
-const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata)
-{
- if (!userdata["avaline_call"].asBoolean())
- return LLUUID::null;
-
- for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it)
- {
- const LLSD& user_info = it->second;
-
- if (user_info["call_number"].asString() == userdata["call_number"].asString())
- return it->first;
- }
-
- return LLUUID::null;
-}
-
// virtual
bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 18b669ff4f..1b322f2c0a 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -62,9 +62,7 @@ public:
* @param id avatar to add.
*
* @param userdata additional information about last interaction party.
- * For example when last interaction party is not an avatar
- * but an avaline caller, additional info (such as phone
- * number, session id and etc.) should be added.
+ * For example session id can be added.
*
* @return false if the avatar is in the list already, true otherwise
*/
@@ -97,13 +95,6 @@ public:
const LLSD& getData(const LLUUID& id) const;
/**
- * Checks whether specific participant is an avaline caller
- *
- * @param id identifier of specific participant
- */
- bool isAvalineCaller(const LLUUID& id) const;
-
- /**
* Set callback to be called when the list changed.
*
* Multiple callbacks can be set.
@@ -122,8 +113,6 @@ public:
private:
- const LLUUID& getIDByPhoneNumber(const LLSD& userdata);
-
typedef std::map<LLUUID, LLSD> recent_people_t;
recent_people_t mPeople;
signal_t mChangedSignal;
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
new file mode 100644
index 0000000000..ef611966ed
--- /dev/null
+++ b/indra/newview/llreflectionmap.cpp
@@ -0,0 +1,274 @@
+/**
+ * @file llreflectionmap.cpp
+ * @brief LLReflectionMap class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmap.h"
+#include "pipeline.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+
+extern F32SecondsImplicit gFrameTimeSeconds;
+
+LLReflectionMap::LLReflectionMap()
+{
+}
+
+void LLReflectionMap::update(U32 resolution, U32 face)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ mLastUpdateTime = gFrameTimeSeconds;
+ llassert(mCubeArray.notNull());
+ llassert(mCubeIndex != -1);
+ //llassert(LLPipeline::sRenderDeferred);
+
+ // make sure we don't walk off the edge of the render target
+ while (resolution > gPipeline.mRT->deferredScreen.getWidth() ||
+ resolution > gPipeline.mRT->deferredScreen.getHeight())
+ {
+ resolution /= 2;
+ }
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
+}
+
+void LLReflectionMap::autoAdjustOrigin()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ if (mGroup)
+ {
+ const LLVector4a* bounds = mGroup->getBounds();
+ auto* node = mGroup->getOctreeNode();
+
+ if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN)
+ {
+ // for terrain, make probes float a couple meters above the highest point in the surface patch
+ mOrigin = bounds[0];
+ mOrigin.getF32ptr()[2] += bounds[1].getF32ptr()[2] + 3.f;
+
+ // update radius to encompass bounding box
+ LLVector4a d;
+ d.setAdd(bounds[0], bounds[1]);
+ d.sub(mOrigin);
+ mRadius = d.getLength3().getF32();
+ mPriority = 1;
+ }
+ else if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ mPriority = 1;
+ // cast a ray towards 8 corners of bounding box
+ // nudge origin towards center of empty space
+
+ if (!node)
+ {
+ return;
+ }
+
+ if (node->isLeaf() || node->getChildCount() > 1 || node->getElementCount() > 0)
+ { // use center of object bounding box for leaf nodes or nodes with multiple child nodes
+ mOrigin = bounds[0];
+
+ LLVector4a start;
+ LLVector4a end;
+
+ LLVector4a size = bounds[1];
+
+ LLVector4a corners[] =
+ {
+ { 1, 1, 1 },
+ { -1, 1, 1 },
+ { 1, -1, 1 },
+ { -1, -1, 1 },
+ { 1, 1, -1 },
+ { -1, 1, -1 },
+ { 1, -1, -1 },
+ { -1, -1, -1 }
+ };
+
+ for (int i = 0; i < 8; ++i)
+ {
+ corners[i].mul(size);
+ corners[i].add(bounds[0]);
+ }
+
+ LLVector4a extents[2];
+ extents[0].setAdd(bounds[0], bounds[1]);
+ extents[1].setSub(bounds[0], bounds[1]);
+
+ bool hit = false;
+ for (int i = 0; i < 8; ++i)
+ {
+ int face = -1;
+ LLVector4a intersection;
+ LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, true, &face, &intersection);
+ if (drawable != nullptr)
+ {
+ hit = true;
+ update_min_max(extents[0], extents[1], intersection);
+ }
+ else
+ {
+ update_min_max(extents[0], extents[1], corners[i]);
+ }
+ }
+
+ if (hit)
+ {
+ mOrigin.setAdd(extents[0], extents[1]);
+ mOrigin.mul(0.5f);
+ }
+
+ // make sure radius encompasses all objects
+ LLSimdScalar r2 = 0.0;
+ for (int i = 0; i < 8; ++i)
+ {
+ LLVector4a v;
+ v.setSub(corners[i], mOrigin);
+
+ LLSimdScalar d = v.dot3(v);
+
+ if (d > r2)
+ {
+ r2 = d;
+ }
+ }
+
+ mRadius = llmax(sqrtf(r2.getF32()), 8.f);
+ }
+ else
+ {
+ // user placed probe
+ mPriority = 2;
+
+ // use center of octree node volume for nodes that are just branches without data
+ mOrigin = node->getCenter();
+
+ // update radius to encompass entire octree node volume
+ mRadius = node->getSize().getLength3().getF32();
+
+ //mOrigin = bounds[0];
+ //mRadius = bounds[1].getLength3().getF32();
+
+ }
+ }
+ }
+ else if (mViewerObject)
+ {
+ mPriority = 64;
+ mOrigin.load3(mViewerObject->getPositionAgent().mV);
+ mRadius = mViewerObject->getScale().mV[0]*0.5f;
+ }
+}
+
+bool LLReflectionMap::intersects(LLReflectionMap* other)
+{
+ // TODO: incorporate getBox
+ LLVector4a delta;
+ delta.setSub(other->mOrigin, mOrigin);
+
+ F32 dist = delta.dot3(delta).getF32();
+
+ F32 r2 = mRadius + other->mRadius;
+
+ r2 *= r2;
+
+ return dist < r2;
+}
+
+extern LLControlGroup gSavedSettings;
+
+F32 LLReflectionMap::getAmbiance()
+{
+ F32 ret = 0.f;
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ }
+
+ return ret;
+}
+
+F32 LLReflectionMap::getNearClip()
+{
+ const F32 MINIMUM_NEAR_CLIP = 0.1f;
+
+ F32 ret = 0.f;
+
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip();
+ }
+
+ return llmax(ret, MINIMUM_NEAR_CLIP);
+}
+
+bool LLReflectionMap::getIsDynamic()
+{
+ if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
+ mViewerObject &&
+ mViewerObject->getVolume())
+ {
+ return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
+ }
+
+ return false;
+}
+
+bool LLReflectionMap::getBox(LLMatrix4& box)
+{
+ if (mViewerObject)
+ {
+ LLVolume* volume = mViewerObject->getVolume();
+ if (volume)
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)mViewerObject;
+
+ if (vobjp->getReflectionProbeIsBox())
+ {
+ glh::matrix4f mv(gGLModelView);
+ glh::matrix4f scale;
+ LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+ mRadius = s.magVec();
+ scale.set_scale(glh::vec3f(s.mV));
+ if (vobjp->mDrawable != nullptr)
+ {
+ glh::matrix4f rm((F32*)vobjp->mDrawable->getWorldMatrix().mMatrix);
+
+ glh::matrix4f rt((F32*)vobjp->getRelativeXform().mMatrix);
+
+ mv = mv * rm * scale; // *rt;
+ mv = mv.inverse();
+
+ box = LLMatrix4(mv.m);
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
new file mode 100644
index 0000000000..cf0bc2ff27
--- /dev/null
+++ b/indra/newview/llreflectionmap.h
@@ -0,0 +1,102 @@
+/**
+ * @file llreflectionmap.h
+ * @brief LLReflectionMap class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llcubemaparray.h"
+#include "llmemory.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+class alignas(16) LLReflectionMap : public LLRefCount
+{
+ LL_ALIGN_NEW
+public:
+ // allocate an environment map of the given resolution
+ LLReflectionMap();
+
+ // update this environment map
+ // resolution - size of cube map to generate
+ void update(U32 resolution, U32 face);
+
+ // for volume partition probes, try to place this probe in the best spot
+ void autoAdjustOrigin();
+
+ // return true if given Reflection Map's influence volume intersect's with this one's
+ bool intersects(LLReflectionMap* other);
+
+ // Get the ambiance value to use for this probe
+ F32 getAmbiance();
+
+ // Get the near clip plane distance to use for this probe
+ F32 getNearClip();
+
+ // Return true if this probe should include avatars in its reflection map
+ bool getIsDynamic();
+
+ // get the encoded bounding box of this probe's influence volume
+ // will only return a box if this probe is associated with a VOVolume
+ // with its reflection probe influence volume to to VOLUME_TYPE_BOX
+ // return false if no bounding box (treat as sphere influence volume)
+ bool getBox(LLMatrix4& box);
+
+ // point at which environment map was last generated from (in agent space)
+ LLVector4a mOrigin;
+
+ // distance from viewer camera
+ F32 mDistance;
+
+ // radius of this probe's affected area
+ F32 mRadius = 16.f;
+
+ // last time this probe was updated (or when its update timer got reset)
+ F32 mLastUpdateTime = 0.f;
+
+ // last time this probe was bound for rendering
+ F32 mLastBindTime = 0.f;
+
+ // cube map used to sample this environment map
+ LLPointer<LLCubeMapArray> mCubeArray;
+ S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array
+
+ // index into array packed by LLReflectionMapManager::getReflectionMaps
+ // WARNING -- only valid immediately after call to getReflectionMaps
+ S32 mProbeIndex = -1;
+
+ // set of any LLReflectionMaps that intersect this map (maintained by LLReflectionMapManager
+ std::vector<LLReflectionMap*> mNeighbors;
+
+ // spatial group this probe is tracking (if any)
+ LLSpatialGroup* mGroup = nullptr;
+
+ // viewer object this probe is tracking (if any)
+ LLViewerObject* mViewerObject = nullptr;
+
+ // what priority should this probe have (higher is higher priority)
+ U32 mPriority = 1;
+};
+
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
new file mode 100644
index 0000000000..19f0a8d089
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -0,0 +1,920 @@
+/**
+ * @file llreflectionmapmanager.cpp
+ * @brief LLReflectionMapManager class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmapmanager.h"
+#include "llviewercamera.h"
+#include "llspatialpartition.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llviewercontrol.h"
+#include "llenvironment.h"
+#include "llstartup.h"
+
+extern BOOL gCubeSnapshot;
+extern BOOL gTeleportDisplay;
+
+LLReflectionMapManager::LLReflectionMapManager()
+{
+ for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
+ {
+ mCubeFree[i] = true;
+ }
+
+ // cube index 0 is reserved for the fallback probe
+ mCubeFree[0] = false;
+}
+
+struct CompareReflectionMapDistance
+{
+
+};
+
+
+struct CompareProbeDistance
+{
+ bool operator()(const LLPointer<LLReflectionMap>& lhs, const LLPointer<LLReflectionMap>& rhs)
+ {
+ return lhs->mDistance < rhs->mDistance;
+ }
+};
+
+// helper class to seed octree with probes
+void LLReflectionMapManager::update()
+{
+ if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot); // assert a snapshot is not in progress
+ if (LLAppViewer::instance()->logoutRequestSent())
+ {
+ return;
+ }
+
+ // =============== TODO -- move to an init function =================
+ initReflectionMaps();
+
+ if (!mRenderTarget.isComplete())
+ {
+ U32 color_fmt = GL_RGB16F;
+ const bool use_depth_buffer = true;
+ const bool use_stencil_buffer = false;
+ U32 targetRes = LL_REFLECTION_PROBE_RESOLUTION * 2; // super sample
+ mRenderTarget.allocate(targetRes, targetRes, color_fmt, use_depth_buffer, use_stencil_buffer, LLTexUnit::TT_RECT_TEXTURE);
+ }
+
+ if (mMipChain.empty())
+ {
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION;
+ U32 count = log2((F32)res) + 0.5f;
+
+ mMipChain.resize(count);
+ for (int i = 0; i < count; ++i)
+ {
+ mMipChain[i].allocate(res, res, GL_RGBA16F, false, false, LLTexUnit::TT_RECT_TEXTURE);
+ res /= 2;
+ }
+ }
+
+
+ if (mDefaultProbe.isNull())
+ {
+ mDefaultProbe = addProbe();
+ mDefaultProbe->mDistance = -4096.f; // hack to make sure the default probe is always first in sort order
+ mDefaultProbe->mRadius = 4096.f;
+ }
+
+ mDefaultProbe->mOrigin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
+
+ LLVector4a camera_pos;
+ camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ // process kill list
+ for (auto& probe : mKillList)
+ {
+ auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe);
+ if (iter != mProbes.end())
+ {
+ deleteProbe(iter - mProbes.begin());
+ }
+ }
+
+ mKillList.clear();
+
+ // process create list
+ for (auto& probe : mCreateList)
+ {
+ mProbes.push_back(probe);
+ }
+
+ mCreateList.clear();
+
+ if (mProbes.empty())
+ {
+ return;
+ }
+
+ bool did_update = false;
+
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
+
+ LLReflectionMap* closestDynamic = nullptr;
+
+ LLReflectionMap* oldestProbe = nullptr;
+
+ if (mUpdatingProbe != nullptr)
+ {
+ did_update = true;
+ doProbeUpdate();
+ }
+
+ for (int i = 0; i < mProbes.size(); ++i)
+ {
+ LLReflectionMap* probe = mProbes[i];
+ if (probe->getNumRefs() == 1)
+ { // no references held outside manager, delete this probe
+ deleteProbe(i);
+ --i;
+ continue;
+ }
+
+ probe->mProbeIndex = i;
+
+ LLVector4a d;
+
+ if (!did_update &&
+ i < mReflectionProbeCount &&
+ (oldestProbe == nullptr || probe->mLastUpdateTime < oldestProbe->mLastUpdateTime))
+ {
+ oldestProbe = probe;
+ }
+
+ if (realtime &&
+ closestDynamic == nullptr &&
+ probe->mCubeIndex != -1 &&
+ probe->getIsDynamic())
+ {
+ closestDynamic = probe;
+ }
+
+ if (probe != mDefaultProbe)
+ {
+ d.setSub(camera_pos, probe->mOrigin);
+ probe->mDistance = d.getLength3().getF32() - probe->mRadius;
+ }
+ }
+
+ if (realtime && closestDynamic != nullptr)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime");
+ // update the closest dynamic probe realtime
+ closestDynamic->autoAdjustOrigin();
+ for (U32 i = 0; i < 6; ++i)
+ {
+ updateProbeFace(closestDynamic, i);
+ }
+ }
+
+ // switch to updating the next oldest probe
+ if (!did_update && oldestProbe != nullptr)
+ {
+ LLReflectionMap* probe = oldestProbe;
+ if (probe->mCubeIndex == -1)
+ {
+ probe->mCubeArray = mTexture;
+
+ probe->mCubeIndex = probe == mDefaultProbe ? 0 : allocateCubeIndex();
+ }
+
+ probe->autoAdjustOrigin();
+
+ mUpdatingProbe = probe;
+ doProbeUpdate();
+ }
+
+ // update distance to camera for all probes
+ std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
+}
+
+LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
+{
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mGroup = group;
+
+ if (group)
+ {
+ probe->mOrigin = group->getOctreeNode()->getCenter();
+ }
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ U32 count = 0;
+ U32 lastIdx = 0;
+ for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested
+ if (mProbes[i]->mCubeIndex != -1)
+ {
+ mProbes[i]->mProbeIndex = count;
+ maps[count++] = mProbes[i];
+ }
+ else
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+ lastIdx = i;
+ }
+
+ // set remaining probe indices to -1
+ for (U32 i = lastIdx+1; i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+
+ // null terminate list
+ if (count < maps.size())
+ {
+ maps[count] = nullptr;
+ }
+}
+
+LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group)
+{
+#if 1
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ OctreeNode* node = group->getOctreeNode();
+ F32 size = node->getSize().getF32ptr()[0];
+ if (size >= 15.f && size <= 17.f)
+ {
+ return addProbe(group);
+ }
+ }
+#endif
+
+#if 0
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN)
+ {
+ OctreeNode* node = group->getOctreeNode();
+ F32 size = node->getSize().getF32ptr()[0];
+ if (size >= 15.f && size <= 17.f)
+ {
+ return addProbe(group);
+ }
+ }
+#endif
+ return nullptr;
+}
+
+LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj)
+{
+ llassert(vobj != nullptr);
+
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mViewerObject = vobj;
+ probe->mOrigin.load3(vobj->getPositionAgent().mV);
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+
+S32 LLReflectionMapManager::allocateCubeIndex()
+{
+ for (int i = 0; i < mReflectionProbeCount; ++i)
+ {
+ if (mCubeFree[i])
+ {
+ mCubeFree[i] = false;
+ return i;
+ }
+ }
+
+ // no cubemaps free, steal one from the back of the probe list
+ for (int i = mProbes.size() - 1; i >= mReflectionProbeCount; --i)
+ {
+ if (mProbes[i]->mCubeIndex != -1)
+ {
+ S32 ret = mProbes[i]->mCubeIndex;
+ mProbes[i]->mCubeIndex = -1;
+ mProbes[i]->mCubeArray = nullptr;
+ return ret;
+ }
+ }
+
+ llassert(false); // should never fail to allocate, something is probably wrong with mCubeFree
+ return -1;
+}
+
+void LLReflectionMapManager::deleteProbe(U32 i)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ LLReflectionMap* probe = mProbes[i];
+
+ llassert(probe != mDefaultProbe);
+
+ if (probe->mCubeIndex != -1)
+ { // mark the cube index used by this probe as being free
+ mCubeFree[probe->mCubeIndex] = true;
+ }
+ if (mUpdatingProbe == probe)
+ {
+ mUpdatingProbe = nullptr;
+ mUpdatingFace = 0;
+ }
+
+ // remove from any Neighbors lists
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end());
+ other->mNeighbors.erase(iter);
+ }
+
+ mProbes.erase(mProbes.begin() + i);
+}
+
+
+void LLReflectionMapManager::doProbeUpdate()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(mUpdatingProbe != nullptr);
+
+ updateProbeFace(mUpdatingProbe, mUpdatingFace);
+
+ if (++mUpdatingFace == 6)
+ {
+ updateNeighbors(mUpdatingProbe);
+ mUpdatingProbe = nullptr;
+ mUpdatingFace = 0;
+ }
+}
+
+void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
+{
+ // hacky hot-swap of camera specific render targets
+ gPipeline.mRT = &gPipeline.mAuxillaryRT;
+ probe->update(mRenderTarget.getWidth(), face);
+ gPipeline.mRT = &gPipeline.mMainRT;
+
+ S32 targetIdx = mReflectionProbeCount;
+
+ if (probe != mUpdatingProbe)
+ { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel
+ targetIdx += 1;
+ }
+
+ gGL.setColorMask(true, true);
+
+ // downsample to placeholder map
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+
+ gReflectionMipProgram.bind();
+
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.matrixMode(gGL.MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.flush();
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
+
+ S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f;
+
+ S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
+ S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
+
+ LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
+ LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip");
+ mMipChain[i].bindTarget();
+ if (i == 0)
+ {
+
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
+ }
+
+ gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
+
+ static LLStaticHashedString resScale("resScale");
+ static LLStaticHashedString znear("znear");
+ static LLStaticHashedString zfar("zfar");
+
+ gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i));
+ gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
+ gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
+
+ gGL.begin(gGL.QUADS);
+
+ gGL.texCoord2f(0, 0);
+ gGL.vertex2f(-1, -1);
+
+ gGL.texCoord2f(res, 0);
+ gGL.vertex2f(1, -1);
+
+ gGL.texCoord2f(res, res);
+ gGL.vertex2f(1, 1);
+
+ gGL.texCoord2f(0, res);
+ gGL.vertex2f(-1, 1);
+ gGL.end();
+ gGL.flush();
+
+ res /= 2;
+
+ S32 mip = i - (mMipChain.size() - mips);
+
+ if (mip >= 0)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip copy");
+ mTexture->bind(0);
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res);
+ //if (i == 0)
+ //{
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ //}
+ mTexture->unbind();
+ }
+ mMipChain[i].flush();
+ }
+
+ gGL.popMatrix();
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
+ gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_RECT_TEXTURE);
+ gReflectionMipProgram.unbind();
+ }
+
+ if (face == 5)
+ {
+ //generate radiance map
+ gRadianceGenProgram.bind();
+ mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+ static LLStaticHashedString sSourceIdx("sourceIdx");
+ gRadianceGenProgram.uniform1i(sSourceIdx, targetIdx);
+
+ mMipChain[0].bindTarget();
+ U32 res = mMipChain[0].getWidth();
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe radiance gen");
+ static LLStaticHashedString sMipLevel("mipLevel");
+ static LLStaticHashedString sRoughness("roughness");
+ static LLStaticHashedString sWidth("u_width");
+
+ gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
+ gRadianceGenProgram.uniform1f(sMipLevel, i);
+ gRadianceGenProgram.uniform1i(sWidth, mMipChain[i].getWidth());
+
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ }
+
+ if (i != mMipChain.size() - 1)
+ {
+ res /= 2;
+ glViewport(0, 0, res, res);
+ }
+ }
+
+ gRadianceGenProgram.unbind();
+
+ //generate irradiance map
+ gIrradianceGenProgram.bind();
+ channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+
+ gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx);
+ mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ int start_mip = 0;
+ // find the mip target to start with based on irradiance map resolution
+ for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip)
+ {
+ if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION)
+ {
+ break;
+ }
+ }
+
+ //for (int i = start_mip; i < mMipChain.size(); ++i)
+ {
+ int i = start_mip;
+ LL_PROFILE_GPU_ZONE("probe irradiance gen");
+ glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight());
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ S32 res = mMipChain[i].getWidth();
+ mIrradianceMaps->bind(channel);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ mTexture->bind(channel);
+ }
+ }
+
+ mMipChain[0].flush();
+
+ gIrradianceGenProgram.unbind();
+ }
+}
+
+void LLReflectionMapManager::rebuild()
+{
+ for (auto& probe : mProbes)
+ {
+ probe->mLastUpdateTime = 0.f;
+ }
+}
+
+void LLReflectionMapManager::shift(const LLVector4a& offset)
+{
+ for (auto& probe : mProbes)
+ {
+ probe->mOrigin.add(offset);
+ }
+}
+
+void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mDefaultProbe == probe)
+ {
+ return;
+ }
+
+ //remove from existing neighbors
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear");
+
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly
+ other->mNeighbors.erase(iter);
+ }
+
+ probe->mNeighbors.clear();
+ }
+
+ // search for new neighbors
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search");
+ for (auto& other : mProbes)
+ {
+ if (other != mDefaultProbe && other != probe)
+ {
+ if (probe->intersects(other))
+ {
+ probe->mNeighbors.push_back(other);
+ other->mNeighbors.push_back(probe);
+ }
+ }
+ }
+ }
+}
+
+void LLReflectionMapManager::updateUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ // structure for packing uniform buffer object
+ // see class3/deferred/reflectionProbeF.glsl
+ struct ReflectionProbeData
+ {
+ LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT]; // object bounding box as needed
+ LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space
+ LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance)
+ GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4];
+ GLint refNeighbor[4096];
+ GLint refmapCount;
+ };
+
+ mReflectionMaps.resize(mReflectionProbeCount);
+ getReflectionMaps(mReflectionMaps);
+
+ ReflectionProbeData rpd;
+
+ // load modelview matrix into matrix 4a
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+
+ S32 count = 0;
+ U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ F32 minimum_ambiance = psky->getReflectionProbeAmbiance();
+
+ for (auto* refmap : mReflectionMaps)
+ {
+ if (refmap == nullptr)
+ {
+ break;
+ }
+
+ llassert(refmap->mProbeIndex == count);
+ llassert(mReflectionMaps[refmap->mProbeIndex] == refmap);
+
+ llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged
+
+ {
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refSphere");
+
+ modelview.affineTransform(refmap->mOrigin, oa);
+ rpd.refSphere[count].set(oa.getF32ptr());
+ rpd.refSphere[count].mV[3] = refmap->mRadius;
+ }
+
+ rpd.refIndex[count][0] = refmap->mCubeIndex;
+ llassert(nc % 4 == 0);
+ rpd.refIndex[count][1] = nc / 4;
+ rpd.refIndex[count][3] = refmap->mPriority;
+
+ // for objects that are reflection probes, use the volume as the influence volume of the probe
+ // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres
+ if (refmap->getBox(rpd.refBox[count]))
+ { // negate priority to indicate this probe has a box influence volume
+ rpd.refIndex[count][3] = -rpd.refIndex[count][3];
+ }
+
+ rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance()), 0.f, 0.f, 0.f);
+
+ S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
+ {
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors");
+ //pack neghbor list
+ for (auto& neighbor : refmap->mNeighbors)
+ {
+ if (ni >= 4096)
+ { // out of space
+ break;
+ }
+
+ GLint idx = neighbor->mProbeIndex;
+ if (idx == -1)
+ {
+ continue;
+ }
+
+ // this neighbor may be sampled
+ rpd.refNeighbor[ni++] = idx;
+ }
+ }
+
+ if (nc == ni)
+ {
+ //no neighbors, tag as empty
+ rpd.refIndex[count][1] = -1;
+ }
+ else
+ {
+ rpd.refIndex[count][2] = ni - nc;
+
+ // move the cursor forward
+ nc = ni;
+ if (nc % 4 != 0)
+ { // jump to next power of 4 for compatibility with ivec4
+ nc += 4 - (nc % 4);
+ }
+ }
+
+
+ count++;
+ }
+
+ rpd.refmapCount = count;
+
+ //copy rpd into uniform buffer object
+ if (mUBO == 0)
+ {
+ glGenBuffers(1, &mUBO);
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer");
+ glBindBuffer(GL_UNIFORM_BUFFER, mUBO);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
+}
+
+void LLReflectionMapManager::setUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ if (mUBO == 0)
+ {
+ updateUniforms();
+ }
+ glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO);
+}
+
+
+void renderReflectionProbe(LLReflectionMap* probe)
+{
+ F32* po = probe->mOrigin.getF32ptr();
+
+ //draw orange line from probe to neighbors
+ gGL.flush();
+ gGL.diffuseColor4f(1, 0.5f, 0, 1);
+ gGL.begin(gGL.LINES);
+ for (auto& neighbor : probe->mNeighbors)
+ {
+ gGL.vertex3fv(po);
+ gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
+ }
+ gGL.end();
+ gGL.flush();
+
+#if 0
+ LLSpatialGroup* group = probe->mGroup;
+ if (group)
+ { // draw lines from corners of object aabb to reflection probe
+
+ const LLVector4a* bounds = group->getBounds();
+ LLVector4a o = bounds[0];
+
+ gGL.flush();
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ F32* c = o.getF32ptr();
+
+ const F32* bc = bounds[0].getF32ptr();
+ const F32* bs = bounds[1].getF32ptr();
+
+ // daaw blue lines from corners to center of node
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.end();
+
+ //draw yellow line from center of node to reflection probe origin
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3fv(po);
+ gGL.end();
+ gGL.flush();
+ }
+#endif
+}
+
+void LLReflectionMapManager::renderDebug()
+{
+ gDebugProgram.bind();
+
+ for (auto& probe : mProbes)
+ {
+ renderReflectionProbe(probe);
+ }
+
+ gDebugProgram.unbind();
+}
+
+void LLReflectionMapManager::initReflectionMaps()
+{
+ if (mTexture.isNull())
+ {
+ mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT);
+
+ mTexture = new LLCubeMapArray();
+
+ // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
+ mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 4, mReflectionProbeCount + 2);
+
+ mIrradianceMaps = new LLCubeMapArray();
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE);
+ }
+
+ if (mVertexBuffer.isNull())
+ {
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, GL_STATIC_DRAW);
+ buff->allocateBuffer(4, 0, TRUE);
+
+ LLStrider<LLVector3> v;
+
+ buff->getVertexStrider(v);
+
+ v[0] = LLVector3(-1, -1, -1);
+ v[1] = LLVector3(1, -1, -1);
+ v[2] = LLVector3(-1, 1, -1);
+ v[3] = LLVector3(1, 1, -1);
+
+ buff->flush();
+
+ mVertexBuffer = buff;
+ }
+}
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
new file mode 100644
index 0000000000..e0a2c00db3
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.h
@@ -0,0 +1,163 @@
+/**
+ * @file llreflectionmapmanager.h
+ * @brief LLReflectionMapManager class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llreflectionmap.h"
+#include "llrendertarget.h"
+#include "llcubemaparray.h"
+#include "llcubemap.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+// number of reflection probes to keep in vram
+#define LL_MAX_REFLECTION_PROBE_COUNT 256
+
+// reflection probe resolution
+#define LL_REFLECTION_PROBE_RESOLUTION 128
+#define LL_IRRADIANCE_MAP_RESOLUTION 64
+
+// reflection probe mininum scale
+#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
+
+class alignas(16) LLReflectionMapManager
+{
+ LL_ALIGN_NEW
+public:
+ enum class DetailLevel
+ {
+ STATIC_ONLY = 0,
+ STATIC_AND_DYNAMIC,
+ REALTIME = 2
+ };
+
+ // allocate an environment map of the given resolution
+ LLReflectionMapManager();
+
+ // maintain reflection probes
+ void update();
+
+ // add a probe for the given spatial group
+ LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr);
+
+ // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size()
+ // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr.
+ // maps -- presized array of Reflection Map pointers
+ void getReflectionMaps(std::vector<LLReflectionMap*>& maps);
+
+ // called by LLSpatialGroup constructor
+ // If spatial group should receive a Reflection Probe, will create one for the specified spatial group
+ LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group);
+
+ // presently hacked into LLViewerObject::setTE
+ // Used by LLViewerObjects that are Reflection Probes
+ // Guaranteed to not return null
+ LLReflectionMap* registerViewerObject(LLViewerObject* vobj);
+
+ // force an update of all probes
+ void rebuild();
+
+ // called on region crossing to "shift" probes into new coordinate frame
+ void shift(const LLVector4a& offset);
+
+ // debug display, called from llspatialpartition if reflection
+ // probe debug display is active
+ void renderDebug();
+
+ // call once at startup to allocate cubemap arrays
+ void initReflectionMaps();
+
+private:
+ friend class LLPipeline;
+
+ // delete the probe with the given index in mProbes
+ void deleteProbe(U32 i);
+
+ // get a free cube index
+ // if no cube indices are free, free one starting from the back of the probe list
+ S32 allocateCubeIndex();
+
+ // update the neighbors of the given probe
+ void updateNeighbors(LLReflectionMap* probe);
+
+ // update UBO used for rendering (call only once per render pipe flush)
+ void updateUniforms();
+
+ // bind UBO used for rendering
+ void setUniforms();
+
+ // render target for cube snapshots
+ // used to generate mipmaps without doing a copy-to-texture
+ LLRenderTarget mRenderTarget;
+
+ std::vector<LLRenderTarget> mMipChain;
+
+ // storage for reflection probe radiance maps (plus two scratch space cubemaps)
+ LLPointer<LLCubeMapArray> mTexture;
+
+ // vertex buffer for pushing verts to filter shaders
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+
+ // storage for reflection probe irradiance maps
+ LLPointer<LLCubeMapArray> mIrradianceMaps;
+
+ // array indicating if a particular cubemap is free
+ bool mCubeFree[LL_MAX_REFLECTION_PROBE_COUNT];
+
+ // start tracking the given spatial group
+ void trackGroup(LLSpatialGroup* group);
+
+ // perform an update on the currently updating Probe
+ void doProbeUpdate();
+
+ // update the specified face of the specified probe
+ void updateProbeFace(LLReflectionMap* probe, U32 face);
+
+ // list of active reflection maps
+ std::vector<LLPointer<LLReflectionMap> > mProbes;
+
+ // list of reflection maps to kill
+ std::vector<LLPointer<LLReflectionMap> > mKillList;
+
+ // list of reflection maps to create
+ std::vector<LLPointer<LLReflectionMap> > mCreateList;
+
+ // handle to UBO
+ U32 mUBO = 0;
+
+ // list of maps being used for rendering
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
+ LLReflectionMap* mUpdatingProbe = nullptr;
+ U32 mUpdatingFace = 0;
+
+ LLPointer<LLReflectionMap> mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0)
+
+ // number of reflection probes to use for rendering (based on saved setting RenderReflectionProbeCount)
+ U32 mReflectionProbeCount;
+};
+
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 055ccd5818..f4ace52faa 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
if (!status)
{
- observer->setErrorStatus(status.getStatus(), status.getMessage());
+ std::string message = status.getMessage();
+ if (message.empty())
+ {
+ message = status.toString();
+ }
+ observer->setErrorStatus(status.getStatus(), message);
}
else
{
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 2e44dc1459..49d5aa3e14 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate()
if(mDiffState == EXECUTE_DIFF)
{
- glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject);
+ glBeginQuery(GL_SAMPLES_PASSED, mQueryObject);
}
gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
if(mDiffState == EXECUTE_DIFF)
{
- glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ glEndQuery(GL_SAMPLES_PASSED);
mDiffState = WAIT_ON_RESULT;
}
@@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult()
mDiffState = WAITING_FOR_NEXT_DIFF;
GLuint available = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available);
if(available)
{
GLuint count = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count);
mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face)
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index f7aa63e34d..e250f9bc7a 100644
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -266,14 +266,11 @@ void LLSceneView::draw()
U32 count = triangles[idx].size();
- U32 total = 0;
-
gGL.begin(LLRender::LINE_STRIP);
//plot triangles
for (U32 i = 0; i < count; ++i)
{
U32 tri_count = triangles[idx][i];
- total += tri_count;
F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom;
F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft;
@@ -290,15 +287,8 @@ void LLSceneView::draw()
gGL.end();
gGL.flush();
- U32 total_visible = 0;
count = visible_triangles[idx].size();
- for (U32 i = 0; i < count; ++i)
- {
- U32 tri_count = visible_triangles[idx][i];
- total_visible += tri_count;
- }
-
std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)",
category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f);
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index e033cae3ab..31f11eb8ef 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -41,9 +41,9 @@ namespace ll
struct PanelData;
struct TabContainerData;
- typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
- typedef boost::shared_ptr< PanelData > PanelDataPtr;
- typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+ typedef std::shared_ptr< SearchableItem > SearchableItemPtr;
+ typedef std::shared_ptr< PanelData > PanelDataPtr;
+ typedef std::shared_ptr< TabContainerData > TabContainerDataPtr;
typedef std::vector< TabContainerData > tTabContainerDataList;
typedef std::vector< SearchableItemPtr > tSearchableItemList;
@@ -55,7 +55,7 @@ namespace ll
LLView const *mView;
ll::ui::SearchableControl const *mCtrl;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
virtual ~SearchableItem();
@@ -68,8 +68,8 @@ namespace ll
LLPanel const *mPanel;
std::string mLabel;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
- std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< PanelData > > mChildPanel;
virtual ~PanelData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 82a165cb35..2475900d0e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -63,6 +63,7 @@
#include "llfloatertools.h"
#include "llframetimer.h"
#include "llfocusmgr.h"
+#include "llgltfmateriallist.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventorymodel.h"
@@ -310,14 +311,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
{
struct f : public LLSelectedNodeFunctor
{
+ f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {}
+ bool mAvatarOverridesPersist;
+ LLSelectMgr* mManager;
virtual bool apply(LLSelectNode* node)
{
+ if (mAvatarOverridesPersist)
+ {
+ LLViewerObject* object = node->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object));
+ }
+ }
+ }
node->mLastPositionLocal.setVec(0, 0, 0);
node->mLastRotation = LLQuaternion();
node->mLastScale.setVec(0, 0, 0);
return true;
}
- } func;
+ } func(mAllowSelectAvatar, this);
selected_handle->applyToNodes(&func);
}
@@ -351,6 +367,93 @@ void LLSelectMgr::overrideObjectUpdates()
getSelection()->applyToNodes(&func);
}
+void LLSelectMgr::resetAvatarOverrides()
+{
+ mAvatarOverridesMap.clear();
+}
+
+void LLSelectMgr::overrideAvatarUpdates()
+{
+ if (mAvatarOverridesMap.size() == 0)
+ {
+ return;
+ }
+
+ if (!mAllowSelectAvatar || !gFloaterTools)
+ {
+ resetAvatarOverrides();
+ return;
+ }
+
+ if (!gFloaterTools->getVisible() && getSelection()->isEmpty())
+ {
+ // when user switches selection, floater is invisible and selection is empty
+ LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset();
+ if (toolset->isShowFloaterTools()
+ && toolset->isToolSelected(0)) // Pie tool
+ {
+ resetAvatarOverrides();
+ return;
+ }
+ }
+
+ // remove selected avatars from this list,
+ // but set object overrides to make sure avatar won't snap back
+ struct f : public LLSelectedNodeFunctor
+ {
+ f(LLSelectMgr* p) : mManager(p) {}
+ LLSelectMgr* mManager;
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID());
+ if (iter != mManager->mAvatarOverridesMap.end())
+ {
+ if (selectNode->mLastPositionLocal.isExactlyZero())
+ {
+ selectNode->mLastPositionLocal = iter->second.mLastPositionLocal;
+ }
+ if (selectNode->mLastRotation == LLQuaternion())
+ {
+ selectNode->mLastRotation = iter->second.mLastRotation;
+ }
+ mManager->mAvatarOverridesMap.erase(iter);
+ }
+ }
+ }
+ return true;
+ }
+ } func(this);
+ getSelection()->applyToNodes(&func);
+
+ // Override avatar positions
+ uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin();
+ while (it != mAvatarOverridesMap.end())
+ {
+ if (it->second.mObject->isDead())
+ {
+ it = mAvatarOverridesMap.erase(it);
+ }
+ else
+ {
+ if (!it->second.mLastPositionLocal.isExactlyZero())
+ {
+ it->second.mObject->setPosition(it->second.mLastPositionLocal);
+ }
+ if (it->second.mLastRotation != LLQuaternion())
+ {
+ it->second.mObject->setRotation(it->second.mLastRotation);
+ }
+ it++;
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// Select just the object, not any other group members.
//-----------------------------------------------------------------------------
@@ -886,7 +989,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
// Can't select yourself
if (objectp->mID == gAgentID
- && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ && !mAllowSelectAvatar)
{
continue;
}
@@ -1066,8 +1169,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
return;
}
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
- || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
+ if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
+ || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
{
// only select my own objects
return;
@@ -1644,6 +1747,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
bool texture_copied = false;
+ bool updated = false;
for (S32 te = 0; te < num_tes; ++te)
{
if (node->isTESelected(te))
@@ -1652,22 +1756,68 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
// without making any copies
if (!texture_copied)
{
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
texture_copied = true;
}
// apply texture for the selected faces
add(LLStatViewer::EDIT_TEXTURE, 1);
object->setTEImage(te, image);
- dialog_refresh_all();
-
- // send the update to the simulator
- object->sendTEUpdate();
+ updated = true;
}
}
+
+ if (updated) // not nessesary? sendTEUpdate update supposed to be done by sendfunc
+ {
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ object->sendTEUpdate();
+ }
}
}
+void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return;
+ }
+
+ LLUUID asset_id = item->getAssetUUID();
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool material_copied = false;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy) materials must be moved to the object's inventory only once
+ // without making any copies
+ if (!material_copied && asset_id.notNull())
+ {
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ material_copied = true;
+ }
+
+ // apply texture for the selected faces
+ //add(LLStatViewer::EDIT_TEXTURE, 1);
+ object->setRenderMaterialID(te, asset_id, false /*will be sent later*/);
+ }
+ }
+ }
+}
+
+
//-----------------------------------------------------------------------------
// selectionSetImage()
//-----------------------------------------------------------------------------
@@ -1760,6 +1910,148 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
//-----------------------------------------------------------------------------
+// selectionSetGLTFMaterial()
+//-----------------------------------------------------------------------------
+void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
+{
+ // First for (no copy) textures and multiple object selection
+ LLViewerInventoryItem* item = gInventory.getItem(mat_id);
+ if (item
+ && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
+ && (mSelectedObjects->getNumNodes() > 1))
+ {
+ LL_WARNS() << "Attempted to apply no-copy material to multiple objects"
+ << LL_ENDL;
+ return;
+ }
+
+ struct f : public LLSelectedTEFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ LLUUID mMatId;
+ f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mMatId(id) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && !objectp->permModify())
+ {
+ return false;
+ }
+ LLUUID asset_id = mMatId;
+ if (mItem)
+ {
+ asset_id = mItem->getAssetUUID();
+ }
+
+ if (asset_id.notNull() && !objectp->hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
+ }
+
+ if (te != -1)
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (asset_id.notNull())
+ {
+ tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ }
+ else
+ {
+ tep->setGLTFMaterial(nullptr);
+ }
+
+ objectp->faceMappingChanged();
+ gPipeline.markTextured(objectp->mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(te, asset_id);
+ }
+ }
+ else // Shouldn't happen?
+ {
+ S32 num_faces = objectp->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ LLTextureEntry* tep = objectp->getTE(face);
+ if (asset_id.notNull())
+ {
+ tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id));
+ }
+ else
+ {
+ tep->setGLTFMaterial(nullptr);
+ }
+
+ objectp->faceMappingChanged();
+ gPipeline.markTextured(objectp->mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(face, asset_id);
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ getSelection()->applyNoCopyPbrMaterialToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, mat_id);
+ getSelection()->applyToTEs(&setfunc);
+ }
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ g(LLViewerInventoryItem* item) : mItem(item) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ if (!mItem)
+ {
+ // 1 particle effect per object
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(object);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
+
+ dialog_refresh_all();
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc(item);
+ getSelection()->applyToObjects(&sendfunc);
+}
+
+//-----------------------------------------------------------------------------
// selectionSetColor()
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionSetColor(const LLColor4 &color)
@@ -1936,6 +2228,59 @@ BOOL LLSelectMgr::selectionRevertTextures()
return revert_successful;
}
+void LLSelectMgr::selectionRevertGLTFMaterials()
+{
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && !objectp->permModify())
+ {
+ return false;
+ }
+
+ LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
+ if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size())
+ {
+ LLUUID asset_id = nodep->mSavedGLTFMaterials[te];
+ objectp->setRenderMaterialID(te, asset_id, false /*wait for bulk update*/);
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ getSelection()->applyToTEs(&setfunc);
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ object->setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc;
+ getSelection()->applyToObjects(&sendfunc);
+}
+
void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
struct f : public LLSelectedTEFunctor
@@ -1965,7 +2310,7 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -2025,7 +2370,7 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -5526,6 +5871,17 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
// this should be the only place that saved textures is called
node->saveTextures(texture_ids);
}
+
+ if (can_copy && can_transfer && node->getObject()->getVolume())
+ {
+ uuid_vec_t material_ids;
+ LLVOVolume* vobjp = (LLVOVolume*)node->getObject();
+ for (int i = 0; i < vobjp->getNumTEs(); ++i)
+ {
+ material_ids.push_back(vobjp->getRenderMaterialID(i));
+ }
+ node->savedGLTFMaterials(material_ids);
+ }
}
node->mValid = TRUE;
@@ -5992,7 +6348,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor)
{
//Need to because crash on ATI 3800 (and similar cards) MAINT-5018
- LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -6277,10 +6633,29 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
}
saveTextures(nodep.mSavedTextures);
+ savedGLTFMaterials(nodep.mSavedGLTFMaterials);
}
LLSelectNode::~LLSelectNode()
{
+ LLSelectMgr *manager = LLSelectMgr::getInstance();
+ if (manager->mAllowSelectAvatar
+ && (!mLastPositionLocal.isExactlyZero()
+ || mLastRotation != LLQuaternion()))
+ {
+ LLViewerObject* object = getObject(); //isDead() check
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ // Avatar was moved and needs to stay that way
+ manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object));
+ }
+ }
+ }
+
+
delete mPermissions;
mPermissions = NULL;
}
@@ -6392,6 +6767,20 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
+void LLSelectNode::savedGLTFMaterials(const uuid_vec_t& materials)
+{
+ if (mObject.notNull())
+ {
+ mSavedGLTFMaterials.clear();
+
+ for (uuid_vec_t::const_iterator materials_it = materials.begin();
+ materials_it != materials.end(); ++materials_it)
+ {
+ mSavedGLTFMaterials.push_back(*materials_it);
+ }
+ }
+}
+
void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
mTextureScaleRatios.clear();
@@ -6788,6 +7177,10 @@ void LLSelectMgr::updateSelectionCenter()
const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
// center (tractor beam)
+ // override any avatar updates received
+ // Works only if avatar was repositioned
+ // and edit floater is visible
+ overrideAvatarUpdates();
//override any object updates received
//for selected objects
overrideObjectUpdates();
@@ -8183,6 +8576,7 @@ DEF_DUMMY_CHECK_FUNCTOR(int)
DEF_DUMMY_CHECK_FUNCTOR(LLColor4)
DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry)
DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLMaterial>)
+DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLGLTFMaterial>)
DEF_DUMMY_CHECK_FUNCTOR(std::string)
DEF_DUMMY_CHECK_FUNCTOR(std::vector<std::string>)
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0316e610..573eea7a8a 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -187,6 +187,7 @@ public:
void saveColors();
void saveShinyColors();
void saveTextures(const uuid_vec_t& textures);
+ void savedGLTFMaterials(const uuid_vec_t& materials);
void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
@@ -224,6 +225,7 @@ public:
std::vector<LLColor4> mSavedColors;
std::vector<LLColor4> mSavedShinyColors;
uuid_vec_t mSavedTextures;
+ uuid_vec_t mSavedGLTFMaterials;
std::vector<LLVector3> mTextureScaleRatios;
std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object
std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
@@ -366,6 +368,7 @@ public:
* Then this only texture is used for all selected faces.
*/
void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+ void applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item);
ESelectType getSelectType() const { return mSelectType; }
@@ -467,6 +470,30 @@ public:
void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
void overrideObjectUpdates();
+ void resetAvatarOverrides();
+ void overrideAvatarUpdates();
+
+ struct AvatarPositionOverride
+ {
+ AvatarPositionOverride();
+ AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) :
+ mLastPositionLocal(vec),
+ mLastRotation(quat),
+ mObject(obj)
+ {
+ }
+ LLVector3 mLastPositionLocal;
+ LLQuaternion mLastRotation;
+ LLPointer<LLViewerObject> mObject;
+ };
+
+ // Avatar overrides should persist even after selection
+ // was removed as long as edit floater is up
+ typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t;
+ uuid_av_override_map_t mAvatarOverridesMap;
+public:
+
+
// Returns the previous value of mForceSelection
BOOL setForceSelection(BOOL force);
@@ -603,12 +630,14 @@ public:
void selectionSetRestitution(F32 restitution);
void selectionSetMaterial(U8 material);
void selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ void selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id
void selectionSetColor(const LLColor4 &color);
void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
void selectionRevertColors();
void selectionRevertShinyColors();
BOOL selectionRevertTextures();
+ void selectionRevertGLTFMaterials();
void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny, const LLUUID &image_id );
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 14a9f4aa30..f9b7c749b3 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -123,7 +123,7 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons
void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
{
- U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
+ U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings");
createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback);
}
@@ -667,17 +667,17 @@ void LLSettingsVOSky::updateSettings()
void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
+ LLVector3 light_direction = LLVector3(LLEnvironment::instance().getClampedLightNorm().mV);
LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());
}
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
// Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
@@ -690,25 +690,30 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
// * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
cloud_scroll[0] = -cloud_scroll[0];
vect_c_p_d1 += cloud_scroll;
- shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1);
+ shader->uniform3fv(LLShaderMgr::CLOUD_POS_DENSITY1, LLVector3(vect_c_p_d1.mV));
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV);
- LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV);
+ // TODO -- make these getters return vec3s
+ LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV);
+ LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV);
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
- shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
- LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0);
- shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color);
+ shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV));
}
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY];
shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
- LLColor4 ambient(getTotalAmbient());
- shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV));
+ LLColor3 ambient(getTotalAmbient());
+
+ shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
+ shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, linearColor3v(getAmbientColor()/3.f)); // note magic number 3.f comes from SLIDER_SCALE_SUN_AMBIENT
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_LINEAR, linearColor3v(getSunlightColor()));
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_LINEAR,linearColor3v(getMoonlightColor()));
+ shader->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, getReflectionProbeAmbiance());
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);
shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
@@ -720,6 +725,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
shader->uniform1f(LLShaderMgr::GAMMA, g);
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma);
+
+ shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon()/2.f)); // note magic number of 2.f comes from SLIDER_SCALE_BLUE_HORIZON_DENSITY
+ shader->uniform3fv(LLShaderMgr::BLUE_DENSITY_LINEAR, linearColor3v(getBlueDensity()/2.f));
+ shader->uniform1f(LLShaderMgr::HAZE_DENSITY_LINEAR, sRGBtoLinear(getHazeDensity()));
}
LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
@@ -758,6 +767,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
param_map[SETTING_SKY_DROPLET_RADIUS] = DefaultParam(LLShaderMgr::DROPLET_RADIUS, sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
param_map[SETTING_SKY_ICE_LEVEL] = DefaultParam(LLShaderMgr::ICE_LEVEL, sky_defaults[SETTING_SKY_ICE_LEVEL]);
+ param_map[SETTING_REFLECTION_PROBE_AMBIANCE] = DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
// AdvancedAtmospherics TODO
// Provide mappings for new shader params here
}
@@ -939,6 +949,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+ LLDrawPoolAlpha::sWaterPlane = waterPlane;
+
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
@@ -953,14 +965,16 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater);
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
- LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
+ LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor());
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color).mV);
+
F32 blend_factor = env.getCurrentWater()->getBlendFactor();
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
// update to normal lightnorm, water shader itself will use rotated lightnorm as necessary
- shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
}
}
@@ -1026,12 +1040,39 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
std::set<std::string> framenames;
std::set<std::string> notfound;
+ // expected and correct folder sctructure is to have
+ // three folders in widnlight's root: days, water, skies
std::string base_path(gDirUtilp->getDirName(path));
std::string water_path(base_path);
std::string sky_path(base_path);
+ std::string day_path(base_path);
gDirUtilp->append(water_path, "water");
gDirUtilp->append(sky_path, "skies");
+ gDirUtilp->append(day_path, "days");
+
+ if (!gDirUtilp->fileExists(day_path))
+ {
+ LL_WARNS("SETTINGS") << "File " << name << ".xml is not in \"days\" folder." << LL_ENDL;
+ }
+
+ if (!gDirUtilp->fileExists(water_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying water folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ water_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(water_path, "water");
+ }
+
+ if (!gDirUtilp->fileExists(sky_path))
+ {
+ LL_WARNS("SETTINGS") << "Failed to find accompaniying skies folder for file " << name
+ << ".xml. Falling back to using default folder" << LL_ENDL;
+
+ sky_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight");
+ gDirUtilp->append(sky_path, "skies");
+ }
newsettings[SETTING_NAME] = name;
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 7fa06f51e3..6216057c17 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -77,7 +77,7 @@ static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
LLSidepanelTaskInfo::LLSidepanelTaskInfo()
{
setMouseOpaque(FALSE);
- LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
+ mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
}
@@ -85,6 +85,11 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
{
if (sActivePanel == this)
sActivePanel = NULL;
+
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
// virtual
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index dc259cb22d..ac9c57f2e2 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -154,6 +154,8 @@ private:
LLView* mDAE;
LLView* mDAN;
LLView* mDAF;
+
+ boost::signals2::connection mSelectionUpdateSlot;
};
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3ab7707df8..61e9d261f7 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -554,9 +554,12 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
sg_assert(mOctreeNode->getListenerCount() == 0);
setState(SG_INITIAL_STATE_MASK);
gPipeline.markRebuild(this, TRUE);
+
+ // let the reflection map manager know about this spatial group
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this);
- mRadius = 1;
- mPixelArea = 1024.f;
+ mRadius = 1;
+ mPixelArea = 1024.f;
}
void LLSpatialGroup::updateDistance(LLCamera &camera)
@@ -1010,11 +1013,11 @@ public:
virtual void processGroup(LLViewerOctreeGroup* base_group)
{
LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- if (group->needsUpdate() ||
+ /*if (group->needsUpdate() ||
group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
{
group->doOcclusion(mCamera);
- }
+ }*/
gPipeline.markNotCulled(group, *mCamera);
}
};
@@ -1399,7 +1402,9 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
return 0;
}
-
+
+extern BOOL gCubeSnapshot;
+
S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
@@ -1418,7 +1423,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
LLOctreeCullShadow culler(&camera);
culler.traverse(mOctree);
}
- else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
+ else if (mInfiniteFarClip || (!LLPipeline::sUseFarClip && !gCubeSnapshot))
{
LLOctreeCullNoFarClip culler(&camera);
culler.traverse(mOctree);
@@ -1567,6 +1572,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
}
}
+// return false if drawable is rigged and:
+// - a linked rigged drawable has a different spatial group
+// - a linked rigged drawable face has the wrong draw order index
+bool check_rigged_group(LLDrawable* drawable)
+{
+ if (drawable->isState(LLDrawable::RIGGED))
+ {
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ LLDrawable* root = drawable->getRoot();
+
+ if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+
+ S32 last_draw_index = -1;
+ if (root->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : root->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ for (auto& child : root->getVObj()->getChildren())
+ {
+ if (child->mDrawable->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : child->mDrawable->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ if (child->mDrawable->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void renderOctree(LLSpatialGroup* group)
{
//render solid object bounding box, color
@@ -1576,7 +1637,7 @@ void renderOctree(LLSpatialGroup* group)
if (group->mBuilt > 0.f)
{
group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
+ if (group->mBufferUsage == GL_STATIC_DRAW)
{
col.setVec(1.0f, 0, 0, group->mBuilt*0.5f);
}
@@ -1586,7 +1647,7 @@ void renderOctree(LLSpatialGroup* group)
//col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f);
}
- if (group->mBufferUsage != GL_STATIC_DRAW_ARB)
+ if (group->mBufferUsage != GL_STATIC_DRAW)
{
LLGLDepthTest gl_depth(FALSE, FALSE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -1611,6 +1672,9 @@ void renderOctree(LLSpatialGroup* group)
{
continue;
}
+
+ llassert(check_rigged_group(drawable));
+
if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
@@ -1681,7 +1745,7 @@ void renderOctree(LLSpatialGroup* group)
}
else
{
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
+ if (group->mBufferUsage == GL_STATIC_DRAW && !group->isEmpty()
&& group->getSpatialPartition()->mRenderByGroup)
{
col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
@@ -1738,7 +1802,7 @@ void renderOctree(LLSpatialGroup* group)
}
}*/
}
-
+
// LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
// gGL.diffuseColor4f(0,1,0,1);
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
@@ -2610,14 +2674,12 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.diffuseColor4fv(line_color.mV);
gGL.syncMatrices();
{
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 )
glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
}
gGL.diffuseColor4fv(color.mV);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
{
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 )
glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
}
}
@@ -3028,7 +3090,7 @@ public:
}
- void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -3070,7 +3132,7 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd();
++iter)
{
@@ -3156,7 +3218,6 @@ void renderRaycast(LLDrawable* drawablep)
gGL.diffuseColor4f(0,1,1,0.5f);
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 );
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
@@ -3164,14 +3225,14 @@ void renderRaycast(LLDrawable* drawablep)
{
F32 t = 1.f;
- if (!face.mOctree)
+ if (!face.getOctree())
{
((LLVolumeFace*) &face)->createOctree();
}
LLRenderOctreeRaycast render(start, dir, &t);
- render.traverse(face.mOctree);
+ render.traverse(face.getOctree());
}
gGL.popMatrix();
@@ -3704,7 +3765,7 @@ void LLSpatialPartition::renderDebug()
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
- LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;
}
@@ -3738,7 +3799,6 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
-
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
{
{
@@ -3787,7 +3847,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
}
LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>
+class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
LL_ALIGN_16(LLVector4a mStart);
@@ -3801,8 +3861,9 @@ public:
LLDrawable* mHit;
BOOL mPickTransparent;
BOOL mPickRigged;
+ BOOL mPickUnselectable;
- LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged,
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable,
S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
@@ -3813,7 +3874,8 @@ public:
mTangent(tangent),
mHit(NULL),
mPickTransparent(pick_transparent),
- mPickRigged(pick_rigged)
+ mPickRigged(pick_rigged),
+ mPickUnselectable(pick_unselectable)
{
}
@@ -3898,7 +3960,7 @@ public:
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -3914,7 +3976,7 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -3934,6 +3996,7 @@ public:
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -3942,12 +4005,30 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
)
{
- LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, face_hit, intersection, tex_coord, normal, tangent);
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
}
+LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+)
+
+{
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* drawable = intersect.check(getOctreeNode());
+
+ return drawable;
+}
+
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
bool selected,
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 6d3ef33801..0d16b818f1 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -41,6 +41,7 @@
#include "llviewercamera.h"
#include "llvector4a.h"
#include "llvoavatar.h"
+#include "llfetchedgltfmaterial.h"
#include <queue>
#include <unordered_map>
@@ -53,6 +54,7 @@ class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
class LLViewerRegion;
+class LLReflectionMap;
void pushVerts(LLFace* face, U32 mask);
@@ -112,9 +114,16 @@ public:
LL_ALIGN_16(LLFace* mFace); //associated face
F32 mDistance;
U32 mDrawMode;
- LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
- LLMaterialID mMaterialID;
- U32 mShaderMask;
+
+ // Material pointer here is likely for debugging only and are immaterial (zing!)
+ LLMaterialPtr mMaterial;
+
+ // PBR material parameters
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+
+ LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
+
+ U32 mShaderMask;
U32 mBlendFuncSrc;
U32 mBlendFuncDst;
BOOL mHasGlow;
@@ -122,6 +131,7 @@ public:
const LLMatrix4* mSpecularMapMatrix;
LLPointer<LLViewerTexture> mNormalMap;
const LLMatrix4* mNormalMapMatrix;
+
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;
@@ -313,6 +323,18 @@ public:
void drawObjectBox(LLColor4 col);
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+
LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
//LISTENER FUNCTIONS
@@ -355,6 +377,9 @@ public:
//used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior
LLVOAvatar* mAvatarp = nullptr;
U32 mRenderOrder = 0;
+ // Reflection Probe associated with this node (if any)
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
+
} LL_ALIGN_POSTFIX(64);
class LLGeometryManager
@@ -382,6 +407,7 @@ public:
LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index abb936c3e5..ea671a130e 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList()
}
else if (mSpeakers.size() == 0)
{
- // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+ // For all other session type (ad-hoc, P2P), we use the initial participants targets list
for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
{
// Add buddies if they are on line, add any other avatar.
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index d1dbf72fe9..ed795b5155 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -245,14 +245,6 @@ public:
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
- * Removes avaline speaker.
- *
- * This is a HACK due to server does not send information that Avaline caller ends call.
- * It can be removed when server is updated. See EXT-4301 for details
- */
- bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); }
-
- /**
* Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.
*
* Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index c3eb70f850..0cdad86a76 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -190,7 +190,7 @@ void LLSprite::updateFace(LLFace &face)
{
LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0,
- GL_STREAM_DRAW_ARB);
+ GL_STREAM_DRAW);
buff->allocateBuffer(4, 12, TRUE);
face.setGeomIndex(0);
face.setIndicesIndex(0);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 98b2bc703b..862db08e62 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -60,6 +60,7 @@
#include "llfloatergridstatus.h"
#include "llfloaterimsession.h"
#include "lllocationhistory.h"
+#include "llgltfmateriallist.h"
#include "llimageworker.h"
#include "llloginflags.h"
@@ -97,6 +98,7 @@
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
+#include "llclassifiedinfo.h"
#include "llconsole.h"
#include "llcontainerview.h"
#include "llconversationlog.h"
@@ -124,8 +126,6 @@
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
-#include "llpanelclassified.h"
-#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@@ -194,6 +194,7 @@
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llpathfindingmanager.h"
+#include "llremoteparcelrequest.h"
#include "lllogin.h"
#include "llevents.h"
@@ -255,6 +256,7 @@ static bool mLoginStatePastUI = false;
static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances
std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
@@ -661,7 +663,7 @@ bool idle_startup()
#else
void* window_handle = NULL;
#endif
- bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
+ bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle());
if(init)
{
gAudiop->setMuted(TRUE);
@@ -927,6 +929,12 @@ bool idle_startup()
LLPersistentNotificationStorage::initParamSingleton();
LLDoNotDisturbNotificationStorage::initParamSingleton();
}
+ else
+ {
+ // reinitialize paths in case user switched grids or accounts
+ LLPersistentNotificationStorage::getInstance()->reset();
+ LLDoNotDisturbNotificationStorage::getInstance()->reset();
+ }
// Set PerAccountSettingsFile to the default value.
std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
@@ -1062,7 +1070,7 @@ bool idle_startup()
{
// Generic failure message
std::ostringstream emsg;
- emsg << LLTrans::getString("LoginFailed") << "\n";
+ emsg << LLTrans::getString("LoginFailedHeader") << "\n";
if(LLLoginInstance::getInstance()->authFailure())
{
LL_INFOS("LLStartup") << "Login failed, LLLoginInstance::getResponse(): "
@@ -1075,11 +1083,37 @@ bool idle_startup()
std::string message_id = response["message_id"];
std::string message; // actual string to show the user
- if(!message_id.empty() && LLTrans::findString(message, message_id, response["message_args"]))
- {
- // message will be filled in with the template and arguments
- }
- else if(!message_response.empty())
+ bool localized_by_id = false;
+ if(!message_id.empty())
+ {
+ LLSD message_args = response["message_args"];
+ if (message_args.has("TIME")
+ && (message_id == "LoginFailedAcountSuspended"
+ || message_id == "LoginFailedAccountMaintenance"))
+ {
+ LLDate date;
+ std::string time_string;
+ if (date.fromString(message_args["TIME"].asString()))
+ {
+ LLSD args;
+ args["datetime"] = (S32)date.secondsSinceEpoch();
+ LLTrans::findString(time_string, "LocalTime", args);
+ }
+ else
+ {
+ time_string = message_args["TIME"].asString() + " " + LLTrans::getString("PacificTime");
+ }
+
+ message_args["TIME"] = time_string;
+ }
+ // message will be filled in with the template and arguments
+ if (LLTrans::findString(message, message_id, message_args))
+ {
+ localized_by_id = true;
+ }
+ }
+
+ if(!localized_by_id && !message_response.empty())
{
// *HACK: "no_inventory_host" sent as the message itself.
// Remove this clause when server is sending message_id as well.
@@ -1252,9 +1286,6 @@ bool idle_startup()
// Initialize classes w/graphics stuff.
//
LLViewerStatsRecorder::instance(); // Since textures work in threads
- gTextureList.doPrefetchImages();
- display_startup();
-
LLSurface::initClasses();
display_startup();
@@ -1362,10 +1393,21 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
}
+ else if (regionp->capabilitiesError())
+ {
+ // Try to connect despite capabilities' error state
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
else
{
U32 num_retries = regionp->getNumSeedCapRetries();
- if (num_retries > 0)
+ if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN)
+ {
+ // Region will keep trying to get capabilities,
+ // but for now continue as if caps were granted
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+ else if (num_retries > 0)
{
LLStringUtil::format_map_t args;
args["[NUMBER]"] = llformat("%d", num_retries + 1);
@@ -1388,6 +1430,12 @@ bool idle_startup()
if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
{
display_startup();
+
+ // These textures are not warrantied to be cached, so needs
+ // to hapen with caps granted
+ gTextureList.doPrefetchImages();
+
+ display_startup();
update_texture_fetch();
display_startup();
@@ -1429,6 +1477,9 @@ bool idle_startup()
gXferManager->registerCallbacks(gMessageSystem);
display_startup();
+ LLGLTFMaterialList::registerCallbacks();
+ display_startup();
+
LLStartUp::initNameCache();
display_startup();
@@ -2359,6 +2410,11 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
+ // We happen to know that instantiating LLVersionInfo implicitly
+ // instantiates the LLEventMailDrop named "relnotes", which we (might) use
+ // below. If viewer release notes stop working, might be because that
+ // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been
+ // instantiated.
if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)
&& LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
@@ -2477,8 +2533,6 @@ void use_circuit_callback(void**, S32 result)
void register_viewer_callbacks(LLMessageSystem* msg)
{
msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
- msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
- msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
@@ -2626,7 +2680,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
-// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ea36e1d7be..1418499f8b 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -681,6 +681,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
}
}
}
+
+ if (did_update)
+ {
+ // some patches changed, update region reflection probes
+ mRegionp->updateReflectionProbes();
+ }
+
return did_update;
}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8f4eb9438b..8b79c7d911 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -987,7 +987,8 @@ void LLTextureCache::setReadOnly(BOOL read_only)
mReadOnly = read_only ;
}
-//called in the main thread.
+// Called in the main thread.
+// Returns the unused amount of max_size if any
S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1c4a56b549..5d9eb48e6c 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -41,13 +41,17 @@
#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
+#include "llmaterialeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llpermissions.h"
+#include "llpreviewtexture.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "lltextbox.h"
@@ -69,16 +73,70 @@
#include "llradiogroup.h"
#include "llfloaterreg.h"
#include "lllocalbitmaps.h"
+#include "lllocalgltfmaterials.h"
#include "llerror.h"
#include "llavatarappearancedefines.h"
-static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
-
-//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
-//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
-//static const char NO_IMAGE_NAME[] = "None";
+//static
+bool get_is_predefined_texture(LLUUID asset_id)
+{
+ if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID"))
+ || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE))
+ {
+ return true;
+ }
+ return false;
+}
+
+LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm)
+{
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(asset_id);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ LLUUID res;
+ if (items.size())
+ {
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ bool allow_trans = item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID());
+ if (allow_trans != no_trans_perm)
+ {
+ return itemp->getUUID();
+ }
+ res = itemp->getUUID();
+ }
+ }
+ }
+ }
+ return res;
+}
+
+bool get_can_copy_texture(LLUUID asset_id)
+{
+ // User is allowed to copy a texture if:
+ // library asset or default texture,
+ // or copy perm asset exists in user's inventory
+
+ return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull();
+}
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
@@ -119,10 +177,11 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mOnFloaterCloseCallback(NULL),
mSetImageAssetIDCallback(NULL),
mOnUpdateImageStatsCallback(NULL),
- mBakeTextureEnabled(FALSE)
+ mBakeTextureEnabled(FALSE),
+ mInventoryPickType(LLTextureCtrl::PICK_TEXTURE)
{
- buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
+ buildFromFile("floater_texture_ctrl.xml");
setCanMinimize(FALSE);
}
@@ -193,10 +252,8 @@ void LLFloaterTexturePicker::setActive( BOOL active )
void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
{
mCanApplyImmediately = b;
- if (!mCanApplyImmediately)
- {
- getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
- }
+
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately);
updateFilterPermMask();
}
@@ -354,12 +411,8 @@ BOOL LLFloaterTexturePicker::postBuild()
childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);
-
- childSetCommitCallback("show_folders_check", onShowFolders, this);
- getChildView("show_folders_check")->setVisible( FALSE);
-
- mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
- mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
@@ -369,12 +422,12 @@ BOOL LLFloaterTexturePicker::postBuild()
if(mInventoryPanel)
{
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
- filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ // to avoid having to make an assumption about which option is
+ // selected at startup, we call the same function that is triggered
+ // when a texture/materials/both choice is made and let it take care
+ // of setting the filters
+ refreshInventoryFilter();
- mInventoryPanel->setFilterTypes(filter_types);
- //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
@@ -407,17 +460,13 @@ BOOL LLFloaterTexturePicker::postBuild()
mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
- LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ refreshLocalList();
mNoCopyTextureSelected = FALSE;
getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
-
- if (!mCanApplyImmediately)
- {
- getChildView("show_folders_check")->setEnabled(FALSE);
- }
+ getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
@@ -445,7 +494,6 @@ void LLFloaterTexturePicker::draw()
updateImageStats();
// if we're inactive, gray out "apply immediate" checkbox
- getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
getChildView("Select")->setEnabled(mActive && mCanApply);
getChildView("Pipette")->setEnabled(mActive);
getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
@@ -460,6 +508,8 @@ void LLFloaterTexturePicker::draw()
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
{
+ // TODO: Fix this! Picker is not warrantied to be connected to a selection
+ // LLSelectMgr shouldn't be used in texture picker
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if (obj)
{
@@ -483,7 +533,7 @@ void LLFloaterTexturePicker::draw()
}
getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
- getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
+ getChildView("Blank")->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID != mDefaultImageAssetID) || mTentative);
getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
LLFloater::draw();
@@ -688,8 +738,18 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
{
- LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- local_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID temp_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ local_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id);
+ }
+ else
+ {
+ local_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ }
}
}
@@ -765,9 +825,6 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
self->getChild<LLFilterEditor>("inventory search editor")->setVisible(index == 0 ? TRUE : FALSE);
self->getChild<LLInventoryPanel>("inventory panel")->setVisible(index == 0 ? TRUE : FALSE);
- /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode);
- no idea under which conditions the above is even shown, needs testing. */
-
self->getChild<LLButton>("l_add_btn")->setVisible(index == 1 ? TRUE : FALSE);
self->getChild<LLButton>("l_rem_btn")->setVisible(index == 1 ? TRUE : FALSE);
self->getChild<LLButton>("l_upl_btn")->setVisible(index == 1 ? TRUE : FALSE);
@@ -836,11 +893,20 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
// static
void LLFloaterTexturePicker::onBtnAdd(void* userdata)
{
- if (LLLocalBitmapMgr::getInstance()->addUnit() == true)
- {
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true);
+ }
}
// static
@@ -851,22 +917,32 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
if (!selected_items.empty())
{
+
for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
iter != selected_items.end(); iter++)
{
LLScrollListItem* list_item = *iter;
if (list_item)
{
- LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->delUnit(tracking_id);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ }
}
}
self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ self->refreshLocalList();
}
-
}
// static
@@ -882,15 +958,29 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata)
/* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
-
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
-
- if (!filename.empty())
- {
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
- }
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ std::string filename;
+ S32 index;
+ LLLocalGLTFMaterialMgr::getInstance()->getFilenameAndIndex(tracking_id, filename, index);
+ if (!filename.empty())
+ {
+ LLMaterialEditor::loadMaterialFromFile(filename, index);
+ }
+ }
+ else
+ {
+ std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
+ if (!filename.empty())
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+ }
}
//static
@@ -906,8 +996,20 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
if (has_selection)
{
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- LLUUID inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+ LLUUID inworld_id;
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ inworld_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
+ }
+ else
+ {
+ inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ }
+
if (self->mSetImageAssetIDCallback)
{
self->mSetImageAssetIDCallback(inworld_id);
@@ -924,22 +1026,6 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
}
// static
-void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)
-{
- LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
-
- if (check_box->get())
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- }
- else
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
- }
-}
-
-// static
void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
{
LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
@@ -1081,6 +1167,48 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
mInventoryPanel->setFilterSubString(search_string);
}
+void LLFloaterTexturePicker::refreshLocalList()
+{
+ mLocalScrollCtrl->clearRows();
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+}
+
+void LLFloaterTexturePicker::refreshInventoryFilter()
+{
+ U32 filter_types = 0x0;
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+
+ mInventoryPanel->setFilterTypes(filter_types);
+}
+
void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
{
mModeSelector->setEnabledByValue(1, enabled);
@@ -1108,6 +1236,55 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
onModeSelect(0, this);
}
+void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ refreshLocalList();
+ refreshInventoryFilter();
+}
+
+void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle)
+{
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ std::string temp_exten = gDirUtilp->getExtension(*iter);
+ if (temp_exten == "gltf" || temp_exten == "glb")
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->addUnit(*iter);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->addUnit(*iter);
+ }
+ }
+ iter++;
+ }
+
+ // Todo: this should referesh all pickers, not just a current one
+ if (!handle.isDead())
+ {
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get();
+ self->mLocalScrollCtrl->clearRows();
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ }
+}
+
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
@@ -1146,7 +1323,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mOnCloseCallback(NULL),
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
- mAllowNoTexture( FALSE ),
+ mAllowNoTexture( p.allow_no_texture ),
mAllowLocalTexture( TRUE ),
mImmediateFilterPermMask( PERM_NONE ),
mNonImmediateFilterPermMask( PERM_NONE ),
@@ -1154,6 +1331,9 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
+ mOpenTexPreview(false),
+ mBakeTextureEnabled(true),
+ mInventoryPickType(PICK_TEXTURE),
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
@@ -1343,14 +1523,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
if (texture_floaterp)
{
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2));
- }
- if (texture_floaterp)
- {
texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
- }
- if (texture_floaterp)
- {
- texture_floaterp->setBakeTextureEnabled(TRUE);
+
+ texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+ texture_floaterp->setInventoryPickType(mInventoryPickType);
}
LLFloater* root_floater = gFloaterView->getParentFloater(this);
@@ -1410,12 +1586,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mBorder->parentPointInView(x, y))
{
- showPicker(FALSE);
- //grab textures first...
- LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
- //...then start full inventory fetch.
- LLInventoryModelBackgroundFetch::instance().start();
- handled = TRUE;
+ if (!mOpenTexPreview)
+ {
+ showPicker(FALSE);
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ //...then start full inventory fetch.
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
+ }
+ else
+ {
+ if (getImageAssetID().notNull())
+ {
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
+ if (preview_texture && !preview_texture->isDependent())
+ {
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(preview_texture);
+ preview_texture->hideCtrlButtons();
+ }
+ }
+ }
+ }
}
return handled;
@@ -1439,9 +1634,9 @@ void LLTextureCtrl::onFloaterClose()
void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp && getEnabled())
+ if( floaterp && getEnabled())
{
if (op == TEXTURE_CANCEL)
mViewModel->resetDirty();
@@ -1462,15 +1657,15 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
else
{
- mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
- LL_DEBUGS() << "mImageItemID: " << mImageItemID << LL_ENDL;
- mImageAssetID = floaterp->getAssetID();
- LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
+ mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+ LL_DEBUGS() << "mImageItemID: " << mImageItemID << LL_ENDL;
+ mImageAssetID = floaterp->getAssetID();
+ LL_DEBUGS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
}
if (op == TEXTURE_SELECT && mOnSelectCallback)
{
- mOnSelectCallback( this, LLSD() );
+ mOnSelectCallback(this, LLSD());
}
else if (op == TEXTURE_CANCEL && mOnCancelCallback)
{
@@ -1481,8 +1676,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
// If the "no_commit_on_selection" parameter is set
// we commit only when user presses OK in the picker
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
- if (mCommitOnSelection || op == TEXTURE_SELECT)
- onCommit();
+ if (mCommitOnSelection || op == TEXTURE_SELECT)
+ {
+ onCommit();
+ }
}
}
}
@@ -1527,8 +1724,9 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
}
}
-void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
+void LLTextureCtrl::setBakeTextureEnabled(bool enabled)
{
+ mBakeTextureEnabled = enabled;
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if (floaterp)
{
@@ -1536,6 +1734,16 @@ void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
}
}
+void LLTextureCtrl::setInventoryPickType(EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setInventoryPickType(type);
+ }
+}
+
BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
@@ -1615,7 +1823,7 @@ void LLTextureCtrl::draw()
}
else//mImageAssetID == LLUUID::null
{
- mTexturep = NULL;
+ mTexturep = NULL;
}
// Border
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 92f6f89af6..0a5a281e76 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -52,6 +52,16 @@ class LLViewerFetchedTexture;
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
+// Helper functions for UI that work with picker
+bool get_is_predefined_texture(LLUUID asset_id);
+
+// texture picker works by asset ids since objects normaly do
+// not retain inventory ids as result these functions are looking
+// for textures in inventory by asset ids
+// This search can be performance unfriendly and doesn't warranty
+// that the texture is original source of asset
+LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false);
+bool get_can_copy_texture(LLUUID image_id);
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
@@ -68,6 +78,13 @@ public:
TEXTURE_CANCEL
} ETexturePickOp;
+ typedef enum e_pick_inventory_type
+ {
+ PICK_TEXTURE_MATERIAL = 0,
+ PICK_TEXTURE = 1,
+ PICK_MATERIAL = 2,
+ } EPickInventoryType;
+
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
@@ -91,7 +108,7 @@ public:
: image_id("image"),
default_image_id("default_image_id"),
default_image_name("default_image_name"),
- allow_no_texture("allow_no_texture"),
+ allow_no_texture("allow_no_texture", false),
can_apply_immediately("can_apply_immediately"),
no_commit_on_selection("no_commit_on_selection", false),
label_width("label_width", -1),
@@ -159,6 +176,8 @@ public:
void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+ void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
@@ -200,7 +219,11 @@ public:
LLViewerFetchedTexture* getTexture() { return mTexturep; }
- void setBakeTextureEnabled(BOOL enabled);
+ void setBakeTextureEnabled(bool enabled);
+ bool getBakeTextureEnabled() const { return mBakeTextureEnabled; }
+
+ void setInventoryPickType(EPickInventoryType type);
+ EPickInventoryType getInventoryPickType() { return mInventoryPickType; };
private:
BOOL allowDrop(LLInventoryItem* item);
@@ -238,6 +261,9 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
+ bool mOpenTexPreview;
+ bool mBakeTextureEnabled;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
};
//////////////////////////////////////////////////////////////////////////////////////////
@@ -315,9 +341,7 @@ public:
//static void onBtnRevert( void* userdata );
static void onBtnBlank(void* userdata);
static void onBtnNone(void* userdata);
- static void onBtnClear(void* userdata);
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
void onTextureSelect(const LLTextureEntry& te);
@@ -333,7 +357,14 @@ public:
void setLocalTextureEnabled(BOOL enabled);
void setBakeTextureEnabled(BOOL enabled);
+ void setInventoryPickType(LLTextureCtrl::EPickInventoryType type);
+
+ static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
+
protected:
+ void refreshLocalList();
+ void refreshInventoryFilter();
+
LLPointer<LLViewerTexture> mTexturep;
LLView* mOwner;
@@ -372,6 +403,7 @@ private:
bool mCanApply;
bool mCanPreview;
bool mPreviewSettingChanged;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
texture_selected_callback mTextureSelectedCallback;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 604444b64a..7cccd6f5ac 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -262,7 +262,6 @@ static const char* e_state_name[] =
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
- "LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@@ -428,7 +427,6 @@ public:
LOAD_FROM_TEXTURE_CACHE,
CACHE_POST,
LOAD_FROM_NETWORK,
- LOAD_FROM_SIMULATOR,
WAIT_HTTP_RESOURCE, // Waiting for HTTP resources
WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources
SEND_HTTP_REQ, // Commit to sending as HTTP
@@ -472,17 +470,11 @@ private:
// Locks: Mw
void clearPackets();
- // Locks: Mw
- void setupPacketData();
// Locks: Mw
void removeFromCache();
// Threads: Ttf
- // Locks: Mw
- bool processSimulatorPackets();
-
- // Threads: Ttf
bool writeToCacheComplete();
// Threads: Ttf
@@ -581,8 +573,7 @@ private:
BOOL mHaveAllData;
BOOL mInLocalCache;
BOOL mInCache;
- bool mCanUseHTTP,
- mCanUseNET ; //can get from asset server.
+ bool mCanUseHTTP;
S32 mRetryAttempt;
S32 mActiveCount;
LLCore::HttpStatus mGetStatus;
@@ -854,7 +845,6 @@ const char* sStateDescs[] = {
"LOAD_FROM_TEXTURE_CACHE",
"CACHE_POST",
"LOAD_FROM_NETWORK",
- "LOAD_FROM_SIMULATOR",
"WAIT_HTTP_RESOURCE",
"WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
@@ -866,7 +856,7 @@ const char* sStateDescs[] = {
"DONE"
};
-const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR,
+const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK,
LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE };
// static
@@ -940,8 +930,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mResourceWaitCount(0U),
mFetchRetryPolicy(10.f,3600.f,2.f,10)
{
- mCanUseNET = mUrl.empty() ;
-
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
if (!mFetcher->mDebugPause)
@@ -1003,39 +991,6 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
-// Locks: Mw
-void LLTextureFetchWorker::setupPacketData()
-{
- S32 data_size = 0;
- if (mFormattedImage.notNull())
- {
- data_size = mFormattedImage->getDataSize();
- }
- if (data_size > 0)
- {
- // Only used for simulator requests
- mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
- if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
- {
- LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL;
- removeFromCache();
- resetFormattedData();
- clearPackets();
- }
- else if (mFileSize > 0)
- {
- mLastPacket = mFirstPacket-1;
- mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
- }
- else
- {
- // This file was cached using HTTP so we have to refetch the first packet
- resetFormattedData();
- clearPackets();
- }
- }
-}
-
// Locks: Mw (ctor invokes without lock)
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
@@ -1127,14 +1082,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mImagePriority < F_ALMOST_ZERO)
{
- if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
+ if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
- if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
+ if(mState > CACHE_POST && !mCanUseHTTP)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
//nowhere to get data, abort.
@@ -1336,10 +1291,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
- if (mHost.isInvalid())
- region = gAgent.getRegion();
- else
- region = LLWorld::getInstance()->getRegion(mHost);
+ if (mHost.isInvalid())
+ {
+ region = gAgent.getRegion();
+ }
+ else if (LLWorld::instanceExists())
+ {
+ region = LLWorld::getInstance()->getRegion(mHost);
+ }
if (region)
{
@@ -1357,14 +1316,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mCanUseHTTP = false ;
- LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
mCanUseHTTP = false;
}
}
@@ -1382,77 +1341,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// don't return, fall through to next state
}
- else if (mSentRequest == UNSENT && mCanUseNET)
- {
- // Add this to the network queue and sit here.
- // LLTextureFetch::update() will send off a request which will change our state
- mWriteToCacheState = CAN_WRITE ;
- mRequestedSize = mDesiredSize;
- mRequestedDiscard = mDesiredDiscard;
- mSentRequest = QUEUED;
- mFetcher->addToNetworkQueue(this);
- recordTextureStart(false);
- return false;
- }
else
{
- // Shouldn't need to do anything here
- //llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
return false;
}
}
- if (mState == LOAD_FROM_SIMULATOR)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR");
- if (mFormattedImage.isNull())
- {
- mFormattedImage = new LLImageJ2C;
- }
- if (processSimulatorPackets())
- {
- // Capture some measure of total size for metrics
- F64 byte_count = 0;
- if (mLastPacket >= mFirstPacket)
- {
- for (S32 i=mFirstPacket; i<=mLastPacket; i++)
- {
- llassert_always((i>=0) && (i<mPackets.size()));
- if (mPackets[i])
- {
- byte_count += mPackets[i]->mSize;
- }
- }
- }
-
- LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
- mFetcher->removeFromNetworkQueue(this, false);
- if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
- {
- // processSimulatorPackets() failed
-// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL;
- LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
- return true; // failed
- }
-
- if (mLoadedDiscard < 0)
- {
- LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
- << ", should be >=0" << LL_ENDL;
- }
- setState(DECODE_IMAGE);
- mWriteToCacheState = SHOULD_WRITE;
-
- recordTextureDone(false, byte_count);
- }
- else
- {
- mFetcher->addToNetworkQueue(this); // failsafe
- recordTextureStart(false);
- }
- return false;
- }
-
if (mState == WAIT_HTTP_RESOURCE)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");
@@ -1496,8 +1390,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL;
return true; // abort
}
-
- mFetcher->removeFromNetworkQueue(this, false);
S32 cur_size = 0;
if (mFormattedImage.notNull())
@@ -1642,17 +1534,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
-
- // roll back to try UDP
- if (mCanUseNET)
- {
- setState(INIT);
- mCanUseHTTP = false;
- mUrl.clear();
- releaseHttpSemaphore();
- //return false;
- return doWork(param);
- }
}
else if (http_service_unavail == mGetStatus)
{
@@ -1868,7 +1749,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL;
- mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, discard, mNeedsAux,
+ mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,
new DecodeResponder(mFetcher, mID, this));
// fall though
}
@@ -2222,69 +2103,6 @@ void LLTextureFetchWorker::removeFromCache()
// Threads: Ttf
// Locks: Mw
-bool LLTextureFetchWorker::processSimulatorPackets()
-{
- if (mFormattedImage.isNull() || mRequestedSize < 0)
- {
- // not sure how we got here, but not a valid state, abort!
- llassert_always(mDecodeHandle == 0);
- mFormattedImage = NULL;
- return true;
- }
-
- if (mLastPacket >= mFirstPacket)
- {
- S32 buffer_size = mFormattedImage->getDataSize();
- for (S32 i = mFirstPacket; i<=mLastPacket; i++)
- {
- llassert_always((i>=0) && (i<mPackets.size()));
- llassert_always(mPackets[i]);
- buffer_size += mPackets[i]->mSize;
- }
- bool have_all_data = mLastPacket >= mTotalPackets-1;
- if (mRequestedSize <= 0)
- {
- // We received a packed but haven't requested anything yet (edge case)
- // Return true (we're "done") since we didn't request anything
- return true;
- }
- if (buffer_size >= mRequestedSize || have_all_data)
- {
- /// We have enough (or all) data
- if (have_all_data)
- {
- mHaveAllData = TRUE;
- }
- S32 cur_size = mFormattedImage->getDataSize();
- if (buffer_size > cur_size)
- {
- /// We have new data
- U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
- S32 offset = 0;
- if (cur_size > 0 && mFirstPacket > 0)
- {
- memcpy(buffer, mFormattedImage->getData(), cur_size);
- offset = cur_size;
- }
- for (S32 i=mFirstPacket; i<=mLastPacket; i++)
- {
- memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize);
- offset += mPackets[i]->mSize;
- }
- // NOTE: setData releases current data
- mFormattedImage->setData(buffer, buffer_size);
- }
- mLoadedDiscard = mRequestedDiscard;
- return true;
- }
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Threads: Ttf
-// Locks: Mw
S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
bool partial, bool success)
{
@@ -2540,7 +2358,7 @@ std::string LLTextureFetch::getStateString(S32 state)
return e_state_name[state];
}
-LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
+LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode)
: LLWorkerThread("TextureFetch", threaded, true),
mDebugCount(0),
mDebugPause(FALSE),
@@ -2549,7 +2367,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mQueueMutex(),
mNetworkQueueMutex(),
mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
@@ -2617,13 +2434,13 @@ LLTextureFetch::~LLTextureFetch()
// ~LLQueuedThread() called here
}
-bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
- return false;
+ return -1;
}
if (f_type == FTT_SERVER_BAKE)
@@ -2639,7 +2456,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
<< host << " != " << worker->mHost << LL_ENDL;
removeRequest(worker, true);
worker = NULL;
- return false;
+ return -1;
}
}
@@ -2692,13 +2509,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
{
if (worker->wasAborted())
{
- return false; // need to wait for previous aborted request to complete
+ return -1; // need to wait for previous aborted request to complete
}
worker->lockWorkMutex(); // +Mw
if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) {
worker->unlockWorkMutex(); // -Mw
- return false; // similar request has failed or is in a transitional state
+ return -1; // similar request has failed or is in a transitional state
}
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
@@ -2733,49 +2550,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex(); // -Mw
}
-
+
LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type)
<< " Discard: " << desired_discard << " size " << desired_size << LL_ENDL;
- return true;
+ return desired_discard;
}
-// Threads: T* (but Ttf in practice)
-
-// protected
-void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
-{
- LL_PROFILE_ZONE_SCOPED;
- lockQueue(); // +Mfq
- bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
- unlockQueue(); // -Mfq
-
- LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
- if (in_request_map)
- {
- // only add to the queue if in the request map
- // i.e. a delete has not been requested
- mNetworkQueue.insert(worker->mID);
- }
- for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
- iter1 != mCancelQueue.end(); ++iter1)
- {
- iter1->second.erase(worker->mID);
- }
-} // -Mfnq
-
-// Threads: T*
-void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
- size_t erased = mNetworkQueue.erase(worker->mID);
- if (cancel && erased > 0)
- {
- mCancelQueue[worker->mHost].insert(worker->mID);
- }
-} // -Mfnq
-
// Threads: T*
//
// protected
@@ -2812,7 +2593,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
- removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@@ -2841,7 +2621,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
- removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
worker->scheduleDelete();
@@ -3138,17 +2917,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)
S32 res = LLWorkerThread::update(max_time_ms);
- if (!mDebugPause)
- {
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the RequestImages message sent by sendRequestListToSimulators
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
- {
- sendRequestListToSimulators();
- }
- }
-
if (!mThreaded)
{
commonUpdate();
@@ -3169,18 +2937,6 @@ void LLTextureFetch::shutDownTextureCacheThread()
}
}
-// called in the MAIN thread after the ImageDecodeThread shuts down.
-//
-// Threads: Tmain
-void LLTextureFetch::shutDownImageDecodeThread()
-{
- if(mImageDecodeThread)
- {
- delete mImageDecodeThread;
- mImageDecodeThread = NULL ;
- }
-}
-
// Threads: Ttf
void LLTextureFetch::startThread()
{
@@ -3235,202 +2991,6 @@ void LLTextureFetch::threadedUpdate()
//////////////////////////////////////////////////////////////////////////////
-// Threads: Tmain
-void LLTextureFetch::sendRequestListToSimulators()
-{
- LL_PROFILE_ZONE_SCOPED;
- // All requests
- const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
-
- // Sim requests
- const S32 IMAGES_PER_REQUEST = 50;
- const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp
- const F32 MIN_REQUEST_TIME = 1.0f;
- const F32 MIN_DELTA_PRIORITY = 1000.f;
-
- // Periodically, gather the list of textures that need data from the network
- // And send the requests out to the simulators
- static LLFrameTimer timer;
- if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME)
- {
- return;
- }
- timer.reset();
-
- // Send requests
- typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
- typedef std::map< LLHost, request_list_t > work_request_map_t;
- work_request_map_t requests;
- {
- LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
- for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
- {
- queue_t::iterator curiter = iter++;
- LLTextureFetchWorker* req = getWorker(*curiter);
- if (!req)
- {
- mNetworkQueue.erase(curiter);
- continue; // paranoia
- }
- if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
- (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
- {
- // We already received our URL, remove from the queue
- LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL;
- mNetworkQueue.erase(curiter);
- continue;
- }
- if (req->mID == mDebugID)
- {
- mDebugCount++; // for setting breakpoints
- }
- if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
- req->mTotalPackets > 0 &&
- req->mLastPacket >= req->mTotalPackets-1)
- {
- // We have all the packets... make sure this is high priority
- continue;
- }
- F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
- {
- F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
- if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
- (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
- (elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
- {
- requests[req->mHost].insert(req);
- }
- }
- }
- } // -Mfnq
-
- for (work_request_map_t::iterator iter1 = requests.begin();
- iter1 != requests.end(); ++iter1)
- {
- LLHost host = iter1->first;
- // invalid host = use agent host
- if (host.isInvalid())
- {
- host = gAgent.getRegionHost();
- }
-
- S32 sim_request_count = 0;
-
- for (request_list_t::iterator iter2 = iter1->second.begin();
- iter2 != iter1->second.end(); ++iter2)
- {
- LLTextureFetchWorker* req = *iter2;
- if (gMessageSystem)
- {
- if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
- {
- // Initialize packet data based on data read from cache
- req->lockWorkMutex(); // +Mw
- req->setupPacketData();
- req->unlockWorkMutex(); // -Mw
- }
- if (0 == sim_request_count)
- {
- gMessageSystem->newMessageFast(_PREHASH_RequestImage);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- S32 packet = req->mLastPacket + 1;
- gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
- gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
- gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
- gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
- gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
- gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
-// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
-// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL;
-
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
- if (log_to_viewer_log || log_to_sim)
- {
- mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
- mTextureInfo.setRequestOffset(req->mID, 0);
- mTextureInfo.setRequestSize(req->mID, 0);
- mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
- }
-
- req->lockWorkMutex(); // +Mw
- req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
- req->mSimRequestedDiscard = req->mDesiredDiscard;
- req->mRequestedPriority = req->mImagePriority;
- req->mRequestedDeltaTimer.reset();
- req->unlockWorkMutex(); // -Mw
- sim_request_count++;
- if (sim_request_count >= IMAGES_PER_REQUEST)
- {
-// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
-
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- sim_request_count = 0;
- }
- }
- }
- if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST)
- {
-// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- sim_request_count = 0;
- }
- }
-
- // Send cancelations
- {
- LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
- if (gMessageSystem && !mCancelQueue.empty())
- {
- for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
- iter1 != mCancelQueue.end(); ++iter1)
- {
- LLHost host = iter1->first;
- if (host.isInvalid())
- {
- host = gAgent.getRegionHost();
- }
- S32 request_count = 0;
- for (queue_t::iterator iter2 = iter1->second.begin();
- iter2 != iter1->second.end(); ++iter2)
- {
- if (0 == request_count)
- {
- gMessageSystem->newMessageFast(_PREHASH_RequestImage);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
- gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
- gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
- gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
- gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
- gMessageSystem->addU8Fast(_PREHASH_Type, 0);
-// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL;
-
- request_count++;
- if (request_count >= IMAGES_PER_REQUEST)
- {
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- request_count = 0;
- }
- }
- if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
- {
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- }
- }
- mCancelQueue.clear();
- }
- } // -Mfnq
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
// Threads: T*
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
@@ -3495,138 +3055,6 @@ void LLTextureFetchWorker::setState(e_state new_state)
mState = new_state;
}
-// Threads: T*
-bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
- U16 data_size, U8* data)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLTextureFetchWorker* worker = getWorker(id);
- bool res = true;
-
- ++mPacketCount;
-
- if (!worker)
- {
-// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL;
- res = false;
- }
- else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
- worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
- {
-// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id
-// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
-// << " sent: " << worker->mSentRequest << LL_ENDL;
- res = false;
- }
- else if (worker->mLastPacket != -1)
- {
- // check to see if we've gotten this packet before
-// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL;
- res = false;
- }
- else if (!data_size)
- {
-// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
- res = false;
- }
- if (!res)
- {
- mNetworkQueueMutex.lock(); // +Mfnq
- ++mBadPacketCount;
- mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock(); // -Mfnq
- return false;
- }
-
- LLViewerStatsRecorder::instance().textureFetch(data_size);
- LLViewerStatsRecorder::instance().log(0.1f);
-
- worker->lockWorkMutex();
-
-
- // Copy header data into image object
- worker->mImageCodec = codec;
- worker->mTotalPackets = packets;
- worker->mFileSize = (S32)totalbytes;
- llassert_always(totalbytes > 0);
- llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
- res = worker->insertPacket(0, data, data_size);
- worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
- worker->unlockWorkMutex(); // -Mw
- return res;
-}
-
-
-// Threads: T*
-bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
-{
- LL_PROFILE_ZONE_SCOPED;
- LLTextureFetchWorker* worker = getWorker(id);
- bool res = true;
-
- ++mPacketCount;
-
- if (!worker)
- {
-// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL;
- res = false;
- }
- else if (worker->mLastPacket == -1)
- {
-// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL;
- res = false;
- }
- else if (!data_size)
- {
-// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
- res = false;
- }
- if (!res)
- {
- mNetworkQueueMutex.lock(); // +Mfnq
- ++mBadPacketCount;
- mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock(); // -Mfnq
- return false;
- }
-
- LLViewerStatsRecorder::instance().textureFetch(data_size);
- LLViewerStatsRecorder::instance().log(0.1f);
-
- worker->lockWorkMutex();
-
-
- res = worker->insertPacket(packet_num, data, data_size);
-
- if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
- (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
- {
- worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
- }
- else
- {
-// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
-// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL;
- removeFromNetworkQueue(worker, true); // failsafe
- }
-
- if (packet_num >= (worker->mTotalPackets - 1))
- {
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
-
- if (log_to_viewer_log || log_to_sim)
- {
- U64Microseconds timeNow = LLTimer::getTotalTime();
- mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
- mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
- }
- }
- worker->unlockWorkMutex(); // -Mw
-
- return res;
-}
-
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@@ -3678,13 +3106,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
if (worker->mFileSize > 0)
{
- if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
- {
- S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE;
- data_size = llmax(data_size, 0);
- data_progress = (F32)data_size / (F32)worker->mFileSize;
- }
- else if (worker->mFormattedImage.notNull())
+ if (worker->mFormattedImage.notNull())
{
data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 320511f343..4297117f75 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -60,7 +60,7 @@ class LLTextureFetch : public LLWorkerThread
public:
static std::string getStateString(S32 state);
- LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
+ LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode);
~LLTextureFetch();
class TFRequest;
@@ -77,7 +77,7 @@ public:
void shutDownImageDecodeThread();
// Threads: T* (but Tmain mostly)
- bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+ S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
// Requests that a fetch operation be deleted from the queue.
@@ -102,12 +102,6 @@ public:
// Threads: T*
bool updateRequestPriority(const LLUUID& id, F32 priority);
- // Threads: T*
- bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
-
- // Threads: T*
- bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
-
// Threads: T* (but not safe)
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
@@ -229,12 +223,6 @@ public:
// ----------------------------------
protected:
- // Threads: T* (but Ttf in practice)
- void addToNetworkQueue(LLTextureFetchWorker* worker);
-
- // Threads: T*
- void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
-
// Threads: T*
void addToHTTPQueue(const LLUUID& id);
@@ -253,9 +241,6 @@ protected:
bool runCondition();
private:
- // Threads: Tmain
- void sendRequestListToSimulators();
-
// Threads: Ttf
/*virtual*/ void startThread(void);
@@ -321,10 +306,9 @@ public:
private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
- LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
+ LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
LLTextureCache* mTextureCache;
- LLImageDecodeThread* mImageDecodeThread;
// Map of all requests by UUID
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
@@ -332,10 +316,8 @@ private:
// Set of requests that require network data
typedef std::set<LLUUID> queue_t;
- queue_t mNetworkQueue; // Mfnq
queue_t mHTTPTextureQueue; // Mfnq
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
- cancel_queue_t mCancelQueue; // Mfnq
F32 mTextureBandwidth; // <none>
F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index f0e9cee101..1f4f086352 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -223,7 +223,6 @@ void LLTextureBar::draw()
{ "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE
{ "DSK", LLColor4::blue }, // CACHE_POST
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
- { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp
new file mode 100644
index 0000000000..c80e87652a
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.cpp
@@ -0,0 +1,183 @@
+/**
+ * @file lltinygltfhelper.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltinygltfhelper.h"
+
+#include "llimage.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+void strip_alpha_channel(LLPointer<LLImageRaw>& img)
+{
+ if (img->getComponents() == 4)
+ {
+ LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3);
+ tmp->copyUnscaled4onto3(img);
+ img = tmp;
+ }
+}
+
+// copy red channel from src_img to dst_img
+// PRECONDITIONS:
+// dst_img must be 3 component
+// src_img and dst_image must have the same dimensions
+void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
+{
+ llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
+ llassert(dst_img->getComponents() == 3);
+
+ U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
+ U8* src = src_img->getData();
+ U8* dst = dst_img->getData();
+ S8 src_components = src_img->getComponents();
+
+ for (U32 i = 0; i < pixel_count; ++i)
+ {
+ dst[i * 3] = src[i * src_components];
+ }
+}
+
+void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex)
+{
+ if (base_color_img)
+ {
+ base_color_tex = LLViewerTextureManager::getFetchedTexture(base_color_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (normal_img)
+ {
+ strip_alpha_channel(normal_img);
+ normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (mr_img)
+ {
+ strip_alpha_channel(mr_img);
+
+ if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
+ {
+ // occlusion is a distinct texture from pbrMetallicRoughness
+ // pack into mr red channel
+ int occlusion_idx = material.occlusionTexture.index;
+ int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (occlusion_idx != mr_idx)
+ {
+ //scale occlusion image to match resolution of mr image
+ occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
+
+ copy_red_channel(occlusion_img, mr_img);
+ }
+ }
+ }
+ else if (occlusion_img)
+ {
+ //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over
+ mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3);
+ mr_img->clear(255, 255, 255);
+ copy_red_channel(occlusion_img, mr_img);
+ }
+
+ if (mr_img)
+ {
+ mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (emissive_img)
+ {
+ strip_alpha_channel(emissive_img);
+ emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true);
+ }
+}
+
+LLColor4 LLTinyGLTFHelper::getColor(const std::vector<double>& in)
+{
+ LLColor4 out;
+ for (S32 i = 0; i < llmin((S32)in.size(), 4); ++i)
+ {
+ out.mV[i] = in[i];
+ }
+
+ return out;
+}
+
+const tinygltf::Image * LLTinyGLTFHelper::getImageFromTextureIndex(const tinygltf::Model & model, S32 texture_index)
+{
+ if (texture_index >= 0)
+ {
+ S32 source_idx = model.textures[texture_index].source;
+ if (source_idx >= 0)
+ {
+ return &(model.images[source_idx]);
+ }
+ }
+
+ return nullptr;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, std::string & name)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ name = image->name;
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ }
+
+ return rawImage;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ }
+
+ return rawImage;
+}
diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h
new file mode 100644
index 0000000000..9c2e5afc17
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.h
@@ -0,0 +1,54 @@
+/**
+ * @file lltinygltfhelper.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+#include "tinygltf/tiny_gltf.h"
+
+class LLImageRaw;
+class LLViewerFetchedTexture;
+
+namespace LLTinyGLTFHelper
+{
+ LLColor4 getColor(const std::vector<double>& in);
+ const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
+
+ void initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex);
+}
+
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8baad30e8f..692e8d91a9 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
- if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 50868d0fa5..3f45d4f0da 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -60,6 +60,7 @@
#include "llvoavatarself.h"
#include "llworld.h"
#include "llpanelface.h"
+#include "lluiusage.h"
// syntactic sugar
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -256,7 +257,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
// |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
@@ -271,6 +273,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+
// TODO: animation on self could play it? edit it?
// TODO: gesture on self could play it? edit it?
};
@@ -921,17 +924,17 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
}
// static
-BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
+BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id)
{
// Always succeed if....
- // texture is from the library
+ // material is from the library
// or already in the contents of the object
if (SOURCE_LIBRARY == source)
{
- // dropping a texture from the library always just works.
+ // dropping a material from the library always just works.
return TRUE;
}
@@ -962,15 +965,15 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- // Check that we can add the texture as inventory to the object
+ // Check that we can add the material as inventory to the object
if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
{
return FALSE;
}
- // make sure the object has the texture in it's inventory.
+ // make sure the object has the material in it's inventory.
if (SOURCE_AGENT == source)
{
- // Remove the texture from local inventory. The server
+ // Remove the material from local inventory. The server
// will actually remove the item from agent inventory.
gInventory.deleteObject(item->getUUID());
gInventory.notifyObservers();
@@ -992,10 +995,11 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
}
}
// Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
- {
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
+ {
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
else
{
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
@@ -1014,9 +1018,10 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
// *FIX: may want to make sure agent can paint hit_obj.
// Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
{
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
else
{
@@ -1043,7 +1048,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
@@ -1062,6 +1067,59 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
hit_obj->sendTEUpdate();
}
+
+void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (hit_face == -1) return;
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL;
+ return;
+ }
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
+
+ hit_obj->setRenderMaterialID(hit_face, asset_id);
+
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
+void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL;
+ return;
+ }
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
+
+ hit_obj->setRenderMaterialIDs(asset_id);
+ dialog_refresh_all();
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
@@ -1073,7 +1131,7 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if(!success)
{
return;
@@ -1100,7 +1158,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
+ const LLUUID& src_id,
+ S32 tex_channel)
{
if (hit_face == -1) return;
if (!item)
@@ -1109,7 +1168,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
@@ -1124,7 +1183,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
if (gFloaterTools->getVisible() && panel_face)
{
- switch (LLSelectMgr::getInstance()->getTextureChannel())
+ tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel();
+ switch (tex_channel)
{
case 0:
@@ -1303,10 +1363,12 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
LLMessageSystem* msg = gMessageSystem;
if (mSource == SOURCE_NOTECARD)
{
+ LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard");
msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
}
else
{
+ LLUIUsage::instance().logCommand("Object.RezObject");
msg->newMessageFast(_PREHASH_RezObject);
}
msg->nextBlockFast(_PREHASH_AgentData);
@@ -1628,6 +1690,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_MESH:
case DAD_CATEGORY:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
@@ -1982,6 +2045,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
dropTextureOneFace(obj, face, item, mSource, mSourceID);
}
}
+ else if (cargo_type == DAD_MATERIAL)
+ {
+ if ((mask & MASK_SHIFT))
+ {
+ dropMaterialAllFaces(obj, item, mSource, mSourceID);
+ }
+ else
+ {
+ dropMaterialOneFace(obj, face, item, mSource, mSourceID);
+ }
+ }
else if (cargo_type == DAD_MESH)
{
dropMesh(obj, item, mSource, mSourceID);
@@ -2010,6 +2084,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject(
return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
}
+EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL);
+}
+
EAcceptance LLToolDragAndDrop::dad3dMeshObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 24a712029c..bf35840964 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -94,7 +94,7 @@ public:
// deal with permissions of object, etc. returns TRUE if drop can
// proceed, otherwise FALSE.
- static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+ static BOOL handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id);
@@ -168,6 +168,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
+ EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face,
+ MASK mask, BOOL drop);
EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
// EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face,
@@ -244,11 +246,20 @@ public:
static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face,
LLInventoryItem* item,
ESource source,
- const LLUUID& src_id);
+ const LLUUID& src_id,
+ S32 tex_channel = -1);
static void dropTextureAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
+ static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
+ static void dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
static void dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 43deac60d9..5fb83bf08e 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -71,6 +71,7 @@
#include "llui.h"
#include "llweb.h"
#include "pipeline.h" // setHighlightObject
+#include "lluiusage.h"
extern BOOL gDebugClicks;
@@ -568,6 +569,8 @@ bool LLToolPie::walkToClickedLocation()
return false;
}
+ LLUIUsage::instance().logCommand("Agent.WalkToClickedLocation");
+
LLPickInfo saved_pick = mPick;
if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
{
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 814bade56a..7cdd7cc5c8 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -62,6 +62,7 @@
#include "llprimitive.h"
#include "llwindow.h" // incBusyCount()
#include "material_codes.h"
+#include "lluiusage.h"
const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
@@ -227,6 +228,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
}
+ LLUIUsage::instance().logCommand("Build.ObjectAdd");
gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index e52bc0b015..c6f3905ddc 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -65,7 +65,8 @@ BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+ BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
+ mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@@ -84,13 +85,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
}
BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
-
- // *NOTE: These settings must be cleaned up at bottom of function.
+
+ // *NOTE: These settings must be cleaned up at bottom of function.
if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
- LLSelectMgr::getInstance()->setForceSelection(TRUE);
+ LLSelectMgr::getInstance()->setForceSelection(TRUE);
}
BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index 4804ef6ddc..481086f760 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -88,6 +88,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
addEntry(LLViewerAssetType::AT_SETTINGS, new ViewerAssetEntry(DAD_SETTINGS));
+ addEntry(LLViewerAssetType::AT_MATERIAL, new ViewerAssetEntry(DAD_MATERIAL));
};
EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type)
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f7e8531fb..3eb9f9eda2 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -50,6 +50,10 @@
#include "llpreviewnotecard.h"
#include "llpreviewgesture.h"
#include "llcoproceduremanager.h"
+#include "llthread.h"
+#include "llkeyframemotion.h"
+#include "lldatapacker.h"
+#include "llvoavatarself.h"
void dialog_refresh_all();
@@ -450,9 +454,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
- else if (assetType == LLAssetType::AT_ANIMATION)
+ else if (exten == "anim")
+ {
+ // Default unless everything succeeds
+ errorLabel = "ProblemWithFile";
+ error = true;
+
+ // read from getFileName()
+ LLAPRFile infile;
+ infile.open(getFileName(),LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
+ errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
+ }
+ else
+ {
+ S32 size = LLAPRFile::size(getFileName());
+ U8* buffer = new U8[size];
+ S32 size_read = infile.read(buffer,size);
+ if (size_read != size)
+ {
+ errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
+ }
+ else
+ {
+ LLDataPackerBinaryBuffer dp(buffer, size);
+ LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
+ motionp->setCharacter(gAgentAvatarp);
+ if (motionp->deserialize(dp, getAssetId(), false))
+ {
+ // write to temp file
+ bool succ = motionp->dumpToFile(filename);
+ if (succ)
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ errorLabel = "";
+ error = false;
+ }
+ else
+ {
+ errorMessage = "Failed saving temporary animation file";
+ }
+ }
+ else
+ {
+ errorMessage = "Failed reading animation file";
+ }
+ }
+ }
+ }
+ else
{
- filename = getFileName();
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
}
if (error)
@@ -497,6 +554,67 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
}
//=========================================================================
+LLNewBufferedResourceUploadInfo::LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish)
+ : LLResourceUploadInfo(name, description, compressionInfo,
+ destinationType, inventoryType,
+ nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory)
+ , mBuffer(buffer)
+ , mFinishFn(finish)
+{
+ setAssetType(assetType);
+ setAssetId(asset_id);
+}
+
+LLSD LLNewBufferedResourceUploadInfo::prepareUpload()
+{
+ if (getAssetId().isNull())
+ generateNewAssetId();
+
+ LLSD result = exportTempFile();
+ if (result.has("error"))
+ return result;
+
+ return LLResourceUploadInfo::prepareUpload();
+}
+
+LLSD LLNewBufferedResourceUploadInfo::exportTempFile()
+{
+ std::string filename = gDirUtilp->getTempFilename();
+
+ // copy buffer to the cache for upload
+ LLFileSystem file(getAssetId(), getAssetType(), LLFileSystem::APPEND);
+ file.write((U8*) mBuffer.c_str(), mBuffer.size());
+
+ return LLSD();
+}
+
+LLUUID LLNewBufferedResourceUploadInfo::finishUpload(LLSD &result)
+{
+ LLUUID newItemId = LLResourceUploadInfo::finishUpload(result);
+
+ if (mFinishFn)
+ {
+ mFinishFn(result["new_asset"].asUUID(), result);
+ }
+
+ return newItemId;
+}
+
+//=========================================================================
LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish) :
LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
0, 0, 0, 0),
@@ -863,6 +981,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
{
args["FILE"] = uploadInfo->getDisplayName();
args["REASON"] = reason;
+ args["ERROR"] = reason;
}
LLNotificationsUtil::add(label, args);
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
index e56ba7d8f7..9eddcfbd0e 100644
--- a/indra/newview/llviewerassetupload.h
+++ b/indra/newview/llviewerassetupload.h
@@ -168,6 +168,41 @@ private:
};
//-------------------------------------------------------------------------
+// use when you have a resource in memory and you want to make a new inventory item
+class LLNewBufferedResourceUploadInfo : public LLResourceUploadInfo
+{
+public:
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> uploadFinish_f;
+
+ LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish);
+
+ virtual LLSD prepareUpload();
+
+protected:
+
+ virtual LLSD exportTempFile();
+ virtual LLUUID finishUpload(LLSD &result);
+
+private:
+ uploadFinish_f mFinishFn;
+ std::string mBuffer;
+};
+
+//-------------------------------------------------------------------------
class LLBufferedAssetUploadInfo : public LLResourceUploadInfo
{
public:
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 782285ce36..febae36ae8 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -33,8 +33,6 @@
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
-#define kAUDIO_NUM_BUFFERS 30
-#define kAUDIO_NUM_SOURCES 30
void init_audio();
void audio_update_volume(bool force_update = true);
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 549778a841..b5841772ed 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -47,15 +47,14 @@ public:
typedef enum
{
CAMERA_WORLD = 0,
- CAMERA_SHADOW0,
- CAMERA_SHADOW1,
- CAMERA_SHADOW2,
- CAMERA_SHADOW3,
- CAMERA_SHADOW4,
- CAMERA_SHADOW5,
+ CAMERA_SUN_SHADOW0,
+ CAMERA_SUN_SHADOW1,
+ CAMERA_SUN_SHADOW2,
+ CAMERA_SUN_SHADOW3,
+ CAMERA_SPOT_SHADOW0,
+ CAMERA_SPOT_SHADOW1,
CAMERA_WATER0,
CAMERA_WATER1,
- CAMERA_GI_SOURCE,
NUM_CAMERAS
} eCameraID;
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 602597a86b..98627f8313 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -381,7 +381,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean()
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
@@ -434,9 +434,25 @@ static bool handleRenderLocalLightsChanged(const LLSD& newvalue)
return true;
}
+static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
+{
+ if (gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ gPipeline.updateRenderDeferred();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
+ return true;
+}
+
+#if 0 // DEPRECATED
+// NOTE: may be triggered by RenderDeferred OR RenderPBR changing, don't trust "newvalue"
static bool handleRenderDeferredChanged(const LLSD& newvalue)
{
- LLRenderTarget::sUseFBO = newvalue.asBoolean();
+ LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
if (gPipeline.isInit())
{
LLPipeline::refreshCachedSettings();
@@ -470,13 +486,7 @@ static bool handleRenderBumpChanged(const LLSD& newval)
}
return true;
}
-
-static bool handleRenderDebugGLChanged(const LLSD& newvalue)
-{
- gDebugGL = newvalue.asBoolean() || gDebugSession;
- gGL.clearErrors();
- return true;
-}
+#endif
static bool handleRenderDebugPipelineChanged(const LLSD& newvalue)
{
@@ -640,157 +650,185 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
+LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
+{
+ LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
+ if (cntrl_ptr.isNull())
+ {
+ LL_ERRS() << "Unable to set up setting listener for " << setting
+ << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ return cntrl_ptr;
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void(const LLSD& newvalue)> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback(new_val);
+ });
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void()> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback();
+ });
+}
+
void settings_setup_listeners()
{
- gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
- gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
- gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
- gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2));
- gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));
- gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
- gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
- gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
- gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
- gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));
- gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));
- gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
- gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
- gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2));
- gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
- gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2));
- gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2));
- gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
- gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
- gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
- gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
- gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
- gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
- gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2));
- gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2));
- gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2));
- gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2));
- gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2));
- gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2));
- gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2));
- gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2));
- gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
- gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
- gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
- gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
- gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
- gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
- gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
- gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
- gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
+ setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
+ // DEPRECATED -- setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
+ // DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
+ // DEPRECATED - setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
+ setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
+ setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
+ setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
+ setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
+ setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
+ setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
+ setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
+ setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
+ setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
+
+ setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 4fc1bdbec3..ed3631be99 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -31,6 +31,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llglheaders.h"
+#include "llgltfmateriallist.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
@@ -97,6 +98,7 @@ BOOL gResizeScreenTexture = FALSE;
BOOL gResizeShadowTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
+BOOL gCubeSnapshot = FALSE;
BOOL gShaderProfileFrame = FALSE;
// This is how long the sim will try to teleport you before giving up.
@@ -160,7 +162,7 @@ void display_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
LLGLSUIDefault gls_ui;
gPipeline.disableLights();
@@ -193,15 +195,23 @@ void display_update_camera()
// Cut draw distance in half when customizing avatar,
// but on the viewer only.
F32 final_far = gAgentCamera.mDrawDistance;
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+ if (gCubeSnapshot)
+ {
+ final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");
+ }
+ else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+
{
final_far *= 0.5f;
}
LLViewerCamera::getInstance()->setFar(final_far);
gViewerWindow->setup3DRender();
- // Update land visibility too
- LLWorld::getInstance()->setLandFarClip(final_far);
+ if (!gCubeSnapshot)
+ {
+ // Update land visibility too
+ LLWorld::getInstance()->setLandFarClip(final_far);
+ }
}
// Write some stats to LL_INFOS()
@@ -245,7 +255,7 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete");
+static LLTrace::BlockTimerStatHandle FTM_MATERIALS_FLUSH("GLTF Materials Cleanup");
static LLTrace::BlockTimerStatHandle FTM_RESIZE_WINDOW("Resize Window");
static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update");
static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom");
@@ -739,7 +749,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
glViewport(0,0,512,512);
- LLVOAvatar::updateFreezeCounter() ;
LLVOAvatar::updateImpostors();
@@ -755,7 +764,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkTextureChannels();
}
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
}
LLGLState::checkStates();
@@ -764,7 +773,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 3")
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
- gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
gPipeline.generateHighlight(*LLViewerCamera::getInstance());
gPipeline.renderPhysicsDisplay();
}
@@ -800,12 +808,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTextureList.updateImages(max_image_decode_time);
}
- /*{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_DELETE);
- //remove dead textures from GL
- LLImageGL::deleteDeadTextures();
- stop_glerror();
- }*/
+ {
+ LL_RECORD_BLOCK_TIME(FTM_MATERIALS_FLUSH);
+ //remove dead gltf materials
+ gGLTFMaterialList.flushMaterials();
+ }
}
LLGLState::checkStates();
@@ -853,7 +860,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
glClearColor(0.5f, 0.5f, 0.5f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
@@ -905,19 +911,27 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (LLPipeline::sRenderDeferred)
{
- gPipeline.mDeferredScreen.bindTarget();
- glClearColor(1, 0, 1, 1);
- gPipeline.mDeferredScreen.clear();
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ F32 g = 0.5f;
+ glClearColor(g, g, g, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
}
else
{
- gPipeline.mScreen.bindTarget();
+ gPipeline.mRT->screen.bindTarget();
if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
{
const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
}
- gPipeline.mScreen.clear();
+ gPipeline.mRT->screen.clear();
}
gGL.setColorMask(true, false);
@@ -954,7 +968,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
}
else
{
@@ -987,19 +1001,19 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
- LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+ LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
- if (rt.sUseFBO)
+ /*if (rt.sUseFBO)
{
LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST);
- }
+ }*/
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderDeferredLighting(&gPipeline.mScreen);
+ gPipeline.renderDeferredLighting();
}
LLPipeline::sUnderWaterRender = FALSE;
@@ -1046,6 +1060,119 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
+// WIP simplified copy of display() that does minimal work
+void display_cube_face()
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER);
+ LL_PROFILE_GPU_ZONE("display cube face");
+
+ llassert(!gSnapshot);
+ llassert(!gTeleportDisplay);
+ llassert(LLStartUp::getStartupState() >= STATE_PRECACHE);
+ llassert(!LLAppViewer::instance()->logoutRequestSent());
+ llassert(!gRestoreGL);
+
+ bool rebuild = false;
+
+ LLGLSDefault gls_default;
+ LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
+
+ LLVertexBuffer::unbind();
+
+ gPipeline.disableLights();
+
+ gPipeline.mBackfaceCull = TRUE;
+
+ gViewerWindow->setup3DViewport();
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ { //don't draw hud objects in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
+ { //don't draw hud particles in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ }
+
+ display_update_camera();
+
+ LLSpatialGroup::sNoDelete = TRUE;
+
+ S32 occlusion = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots
+ //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data
+
+ static LLCullResult result;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
+ gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
+
+ gGL.setColorMask(true, true);
+
+ glClearColor(0, 0, 0, 0);
+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
+
+ glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
+
+ {
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
+
+ if (rebuild)
+ {
+ //////////////////////////////////////
+ //
+ // rebuildPools
+ //
+ //
+ gPipeline.rebuildPools();
+ stop_glerror();
+ }
+ }
+
+ LLPipeline::sUseOcclusion = occlusion;
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
+
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
+
+ gGL.setColorMask(true, true);
+
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ glClearColor(0.5f, 0.5f, 0.5f, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
+
+ gGL.setColorMask(true, false);
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+
+ gGL.setColorMask(true, true);
+
+ gPipeline.mRT->deferredScreen.flush();
+
+ gPipeline.renderDeferredLighting();
+
+ LLPipeline::sUnderWaterRender = FALSE;
+
+ // Finalize scene
+ //gPipeline.renderFinalize();
+
+ LLSpatialGroup::sNoDelete = FALSE;
+ gPipeline.clearReferences();
+
+ gPipeline.rebuildGroups();
+}
+
void render_hud_attachments()
{
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -1108,6 +1235,8 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_POST_WATER);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
@@ -1124,7 +1253,7 @@ void render_hud_attachments()
gPipeline.stateSort(hud_cam, result);
- gPipeline.renderGeom(hud_cam);
+ gPipeline.renderGeomPostDeferred(hud_cam);
LLSpatialGroup::sNoDelete = FALSE;
//gPipeline.clearReferences();
@@ -1240,7 +1369,7 @@ bool setup_hud_matrices(const LLRect& screen_region)
void render_ui(F32 zoom_factor, int subfield)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
-
+ LL_PROFILE_GPU_ZONE("ui");
LLGLState::checkStates();
glh::matrix4f saved_view = get_current_modelview();
@@ -1261,10 +1390,10 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- // Finalize scene
- gPipeline.renderFinalize();
-
{
+ // draw hud and 3D ui elements into screen render target so they'll be able to use
+ // the depth buffer (avoids extra copy of depth buffer per frame)
+ gPipeline.mRT->screen.bindTarget();
// SL-15709
// NOTE: Tracy only allows one ZoneScoped per function.
// Solutions are:
@@ -1281,41 +1410,45 @@ void render_ui(F32 zoom_factor, int subfield)
gPipeline.disableLights();
}
- {
- gGL.color4f(1,1,1,1);
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- if (!gDisconnected)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
- render_ui_3d();
- LLGLState::checkStates();
- }
- else
- {
- render_disconnected_background();
- }
+ gGL.color4f(1,1,1,1);
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
- render_ui_2d();
- LLGLState::checkStates();
- }
- gGL.flush();
+ bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ if (render_ui)
+ {
+ if (!gDisconnected)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+ render_ui_3d();
+ LLGLState::checkStates();
+ }
+ else
+ {
+ render_disconnected_background();
+ }
+ }
- gViewerWindow->setup2DRender();
- gViewerWindow->updateDebugText();
- gViewerWindow->drawDebugText();
+ gPipeline.mRT->screen.flush();
- LLVertexBuffer::unbind();
- }
+ // apply gamma correction and post effects before rendering 2D UI
+ gPipeline.renderFinalize();
- if (!gSnapshot)
- {
- set_current_modelview(saved_view);
- gGL.popMatrix();
- }
+ if (render_ui)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
+ LLHUDObject::renderAll();
+ render_ui_2d();
+ }
+
+ gViewerWindow->setup2DRender();
+ gViewerWindow->updateDebugText();
+ gViewerWindow->drawDebugText();
+ }
- } // Tracy integration
+ if (!gSnapshot)
+ {
+ set_current_modelview(saved_view);
+ gGL.popMatrix();
+ }
}
static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
@@ -1323,7 +1456,7 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
void swap()
{
LL_RECORD_BLOCK_TIME(FTM_SWAP);
-
+ LL_PROFILE_GPU_ZONE("swap");
if (gDisplaySwapBuffers)
{
gViewerWindow->getWindow()->swapBuffers();
@@ -1485,7 +1618,7 @@ void render_ui_2d()
LLView::sIsRectDirty = false;
LLRect t_rect;
- gPipeline.mUIScreen.bindTarget();
+ gPipeline.mRT->uiScreen.bindTarget();
gGL.setColorMask(true, true);
{
static const S32 pad = 8;
@@ -1517,7 +1650,7 @@ void render_ui_2d()
gViewerWindow->draw();
}
- gPipeline.mUIScreen.flush();
+ gPipeline.mRT->uiScreen.flush();
gGL.setColorMask(true, false);
LLView::sDirtyRect = t_rect;
@@ -1527,7 +1660,7 @@ void render_ui_2d()
LLGLDisable blend(GL_BLEND);
S32 width = gViewerWindow->getWindowWidthScaled();
S32 height = gViewerWindow->getWindowHeightScaled();
- gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen);
+ gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.color4f(1,1,1,1);
gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 0000000000..cec08c4f15
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,226 @@
+/**
+ * @file llviewerdisplayname.cpp
+ * @brief Wrapper for display name functionality
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerdisplayname.h"
+
+// viewer includes
+#include "llagent.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+
+// library includes
+#include "llavatarnamecache.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llui.h" // getLanguage()
+
+namespace LLViewerDisplayName
+{
+ // Fired when viewer receives server response to display name change
+ set_name_signal_t sSetDisplayNameSignal;
+
+ // Fired when there is a change in the agent's name
+ name_changed_signal_t sNameChangedSignal;
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
+ {
+ sNameChangedSignal.connect(cb);
+ }
+
+ void doNothing() { }
+}
+
+void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
+{
+ // TODO: simple validation here
+
+ LLViewerRegion* region = gAgent.getRegion();
+ llassert(region);
+ std::string cap_url = region->getCapability("SetDisplayName");
+ if (cap_url.empty())
+ {
+ // this server does not support display names, report error
+ slot(false, "unsupported", LLSD());
+ return;
+ }
+
+ // People API requires both the old and new value to change a variable.
+ // Our display name will be in cache before the viewer's UI is available
+ // to request a change, so we can use direct lookup without callback.
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
+ {
+ slot(false, "name unavailable", LLSD());
+ return;
+ }
+
+ // People API expects array of [ "old value", "new value" ]
+ LLSD change_array = LLSD::emptyArray();
+ change_array.append(av_name.getDisplayName());
+ change_array.append(display_name);
+
+ LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
+
+ // Record our caller for when the server sends back a reply
+ sSetDisplayNameSignal.connect(slot);
+
+ // POST the requested change. The sim will not send a response back to
+ // this request directly, rather it will send a separate message after it
+ // communicates with the back-end.
+ LLSD body;
+ body["display_name"] = change_array;
+ LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro",
+ boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body));
+}
+
+void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ // People API can return localized error messages. Indicate our
+ // language preference via header.
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage());
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL;
+ LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+}
+
+class LLSetDisplayNameReply : public LLHTTPNode
+{
+ LOG_CLASS(LLSetDisplayNameReply);
+public:
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+
+ S32 status = body["status"].asInteger();
+ bool success = (status == HTTP_OK);
+ std::string reason = body["reason"].asString();
+ LLSD content = body["content"];
+
+ LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
+
+ // If viewer's concept of display name is out-of-date, the set request
+ // will fail with 409 Conflict. If that happens, fetch up-to-date
+ // name information.
+ if (status == HTTP_CONFLICT)
+ {
+ LLUUID agent_id = gAgent.getID();
+ // Flush stale data
+ LLAvatarNameCache::getInstance()->erase( agent_id );
+ // Queue request for new data: nothing to do on callback though...
+ // Note: no need to disconnect the callback as it never gets out of scope
+ LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
+ // Kill name tag, as it is wrong
+ LLVOAvatar::invalidateNameTag( agent_id );
+ }
+
+ // inform caller of result
+ LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+};
+
+
+class LLDisplayNameUpdate : public LLHTTPNode
+{
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+ LLUUID agent_id = body["agent_id"];
+ std::string old_display_name = body["old_display_name"];
+ // By convention this record is called "agent" in the People API
+ LLSD name_data = body["agent"];
+
+ // Inject the new name data into cache
+ LLAvatarName av_name;
+ av_name.fromLLSD( name_data );
+
+ LL_INFOS() << "name-update now " << LLDate::now()
+ << " next_update " << LLDate(av_name.mNextUpdate)
+ << LL_ENDL;
+
+ // Name expiration time may be provided in headers, or we may use a
+ // default value
+ // *TODO: get actual headers out of ResponsePtr
+ //LLSD headers = response->mHeaders;
+ LLSD headers;
+ av_name.mExpires =
+ LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers);
+
+ LLAvatarNameCache::getInstance()->insert(agent_id, av_name);
+
+ // force name tag to update
+ LLVOAvatar::invalidateNameTag(agent_id);
+
+ LLSD args;
+ args["OLD_NAME"] = old_display_name;
+ args["SLID"] = av_name.getUserName();
+ args["NEW_NAME"] = av_name.getDisplayName();
+ LLNotificationsUtil::add("DisplayNameUpdate", args);
+ if (agent_id == gAgent.getID())
+ {
+ LLViewerDisplayName::sNameChangedSignal();
+ }
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
+ if (profile_floater)
+ {
+ profile_floater->refreshName();
+ }
+ }
+};
+
+LLHTTPRegistration<LLSetDisplayNameReply>
+ gHTTPRegistrationMessageSetDisplayNameReply(
+ "/message/SetDisplayNameReply");
+
+LLHTTPRegistration<LLDisplayNameUpdate>
+ gHTTPRegistrationMessageDisplayNameUpdate(
+ "/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
new file mode 100644
index 0000000000..337aaa68b6
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,55 @@
+/**
+ * @file llviewerdisplayname.h
+ * @brief Wrapper for display name functionality
+ *
+ * $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$
+ */
+
+#ifndef LLVIEWERDISPLAYNAME_H
+#define LLVIEWERDISPLAYNAME_H
+
+#include <boost/signals2.hpp>
+
+class LLSD;
+class LLUUID;
+
+namespace LLViewerDisplayName
+{
+ typedef boost::signals2::signal<
+ void (bool success, const std::string& reason, const LLSD& content)>
+ set_name_signal_t;
+ typedef set_name_signal_t::slot_type set_name_slot_t;
+
+ typedef boost::signals2::signal<void (void)> name_changed_signal_t;
+ typedef name_changed_signal_t::slot_type name_changed_slot_t;
+
+ // Sends an update to the server to change a display name
+ // and call back when done. May not succeed due to service
+ // unavailable or name not available.
+ void set(const std::string& display_name, const set_name_slot_t& slot);
+
+ void setDisplayNameCoro(const std::string& cap_url, const LLSD& body);
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
+}
+
+#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 5a3a358173..f5ccc238c0 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -57,11 +57,13 @@
#include "llfloatercamera.h"
#include "llfloatercamerapresets.h"
#include "llfloaterchatvoicevolume.h"
+#include "llfloaterclassified.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
+#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
@@ -111,6 +113,7 @@
#include "llfloaterpreference.h"
#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
+#include "llfloaterprofile.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@@ -140,7 +143,6 @@
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@@ -151,10 +153,11 @@
#include "llinspectobject.h"
#include "llinspectremoteobject.h"
#include "llinspecttoast.h"
+#include "llmaterialeditor.h"
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
-#include "llpanelclassified.h"
+#include "llpanelprofileclassifieds.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -227,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
+ LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@@ -274,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
+ LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@@ -315,7 +320,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
@@ -332,6 +336,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
+ LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
+
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
@@ -362,8 +368,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
- LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
- LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
+ LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index f770db31dd..c8d4aae8fd 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -134,6 +134,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
+ addEntry(LLFolderType::FT_MATERIAL, new ViewerFolderEntry("Materials", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 55ac817479..b4feafb7ff 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -147,6 +147,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
+ mInventoryItemsDict["New Material"] = LLTrans::getString("New Material");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
@@ -998,6 +999,21 @@ void create_notecard_cb(const LLUUID& inv_item)
}
}
+void create_gltf_material_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ set_default_permissions(item, "Materials");
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
LLInventoryCallbackManager gInventoryCallbacks;
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
@@ -1622,6 +1638,13 @@ void create_new_item(const std::string& name,
next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards");
break;
}
+
+ case LLInventoryType::IT_MATERIAL:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_gltf_material_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ break;
+ }
default:
break;
}
@@ -1672,6 +1695,7 @@ void remove_folder_contents(const LLUUID& category, bool keep_outfit_links,
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
+const std::string NEW_MATERIAL_NAME = "New Material"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
@@ -1727,6 +1751,15 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
LLInventoryType::IT_GESTURE,
PERM_ALL); // overridden in create_new_item
}
+ else if ("material" == type_name)
+ {
+ const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ create_new_item(NEW_MATERIAL_NAME,
+ parent_id,
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_MATERIAL,
+ PERM_ALL); // overridden in create_new_item
+ }
else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name))
{
LLSettingsType::type_e stype(LLSettingsType::ST_NONE);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 812f804ea9..a1cb152e1e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -48,7 +48,7 @@
#include "llmutelist.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
-#include "llpanelprofile.h"
+#include "llavataractions.h"
#include "llparcel.h"
#include "llpluginclassmedia.h"
#include "llurldispatcher.h"
@@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
}
// If this media's class is not supposed to be shown, unload
- if (!shouldShowBasedOnClass())
+ if (!shouldShowBasedOnClass() || isObscured())
{
return true;
}
@@ -3881,6 +3881,40 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
//////////////////////////////////////////////////////////////////////////////////////////
//
+bool LLViewerMediaImpl::isObscured() const
+{
+ if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false;
+
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ return false;
+ }
+
+ if (agent_parcel->getObscureMOAP() && !isInAgentParcel())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLViewerMediaImpl::isAttachedToHUD() const
+{
+ std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
+ std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
+ for ( ; iter != end; iter++)
+ {
+ if ((*iter)->isHUDAttachment())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
{
bool result = false;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 806692929a..f1f42afd81 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -411,6 +411,8 @@ public:
void cancelMimeTypeProbe();
+ bool isAttachedToHUD() const;
+
// Is this media attached to an avatar *not* self
bool isAttachedToAnotherAvatar() const;
@@ -423,6 +425,7 @@ public:
private:
bool isAutoPlayable() const;
bool shouldShowBasedOnClass() const;
+ bool isObscured() const;
static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
static bool isObjectInAgentParcel(LLVOVolume *obj);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index d95948ac04..e1b92e5f2e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -33,10 +33,11 @@
#include "llviewermenu.h"
// linden library includes
-#include "llavatarnamecache.h" // IDEVO
+#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
+#include "llcombobox.h"
+#include "llcoros.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
-#include "llcombobox.h"
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
@@ -53,6 +54,7 @@
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldebugview.h"
+#include "lldiskcache.h"
#include "llenvironment.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
@@ -91,8 +93,10 @@
#include "llpanelblockedlist.h"
#include "llpanelmaininventory.h"
#include "llmarketplacefunctions.h"
+#include "llmaterialeditor.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
+#include "llnavigationbar.h"
#include "llparcel.h"
#include "llrootview.h"
#include "llsceneview.h"
@@ -267,16 +271,11 @@ void handle_reset_view();
void handle_duplicate_in_place(void*);
-
void handle_object_owner_self(void*);
void handle_object_owner_permissive(void*);
void handle_object_lock(void*);
void handle_object_asset_ids(void*);
void force_take_copy(void*);
-#ifdef _CORY_TESTING
-void force_export_copy(void*);
-void force_import_geometry(void*);
-#endif
void handle_force_parcel_owner_to_me(void*);
void handle_force_parcel_to_content(void*);
@@ -398,7 +397,19 @@ void set_merchant_SLM_menu()
// All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(TRUE);
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
- gToolBarView->enableCommand(command->id(), true);
+ gToolBarView->enableCommand(command->id(), true);
+
+ const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ if (marketplacelistings_id.isNull())
+ {
+ U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
+ bool is_merchant = (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) || (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT);
+ if (is_merchant)
+ {
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, true);
+ LL_WARNS("SLM") << "Creating the marketplace listings folder for a merchant" << LL_ENDL;
+ }
+ }
}
void check_merchant_status(bool force)
@@ -1081,6 +1092,10 @@ U64 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_IMPOSTORS;
}
+ else if ("reflection probes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
+ }
else
{
LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
@@ -1197,6 +1212,7 @@ class LLAdvancedCheckFrameTest : public view_listener_t
///////////////////////////
// SELECTED TEXTURE INFO //
+//
///////////////////////////
@@ -1218,24 +1234,6 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
- gWindowResized = TRUE;
-
- LLPipeline::updateRenderDeferred();
-
- if (gUseWireframe)
- {
- gInitialDeferredModeForWireframe = LLPipeline::sRenderDeferred;
- }
-
- gPipeline.resetVertexBuffers();
-
- if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != bool(gInitialDeferredModeForWireframe) && gPipeline.isInit())
- {
- LLPipeline::refreshCachedSettings();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- LLViewerShaderMgr::instance()->setShaders();
- }
return true;
}
@@ -1245,8 +1243,7 @@ class LLAdvancedCheckWireframe : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gUseWireframe;
- return new_value;
+ return gUseWireframe;
}
};
@@ -2088,6 +2085,32 @@ class LLAdvancedDropPacket : public view_listener_t
}
};
+//////////////////////
+// PURGE DISK CACHE //
+//////////////////////
+
+
+class LLAdvancedPurgeDiskCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ main_queue->postTo(
+ general_queue,
+ []() // Work done on general queue
+ {
+ LLDiskCache::getInstance()->purge();
+ // Nothing needed to return
+ },
+ [](){}); // Callback to main thread is empty as there is nothing left to do
+
+ return true;
+ }
+};
+
////////////////////
// EVENT Recorder //
@@ -2298,59 +2321,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t
}
};
-/////////////////////////////////////
-// Enable Object Object Occlusion ///
-/////////////////////////////////////
-class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
-
- bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString());
- return new_value;
-}
-};
-
-/////////////////////////////////////
-// Enable Framebuffer Objects ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderFBO: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject;
- return new_value;
- }
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferred: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
- return new_value;
- }
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering sub-options
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
- return new_value;
- }
-};
-
-
-
//////////////////
// ADMIN STATUS //
//////////////////
@@ -2395,6 +2365,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
return true;
}
};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2404,6 +2375,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
}
};
+class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorBadMemoryAccessCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_bad_memory_access(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2422,6 +2409,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t
}
};
+class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorSoftwareExceptionCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_software_exception(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2705,6 +2708,32 @@ void handle_object_touch()
send_ObjectDeGrab_message(object, pick);
}
+void handle_object_show_original()
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ return;
+ }
+
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+
+ if (!object || object->isAvatar())
+ {
+ return;
+ }
+
+ show_item_original(object->getAttachmentItemID());
+}
static void init_default_item_label(const std::string& item_name)
@@ -2780,6 +2809,39 @@ void handle_object_open()
LLFloaterReg::showInstance("openobject");
}
+struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEGetFunctor<LLUUID>
+{
+ LLSelectedTEGetmatIdAndPermissions() : mCanCopy(true), mCanModify(true), mCanTransfer(true) {}
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ mCanCopy &= (bool)object->permCopy();
+ mCanTransfer &= (bool)object->permTransfer();
+ mCanModify &= (bool)object->permModify();
+ // return true if all ids are identical
+ return object->getRenderMaterialID(te_index);
+ }
+ bool mCanCopy;
+ bool mCanModify;
+ bool mCanTransfer;
+};
+
+bool enable_object_edit_gltf_material()
+{
+ LLSelectedTEGetmatIdAndPermissions func;
+ LLUUID mat_id;
+ LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+
+ return func.mCanModify;
+}
+
+bool enable_object_save_gltf_material()
+{
+ LLSelectedTEGetmatIdAndPermissions func;
+ LLUUID mat_id;
+ LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, mat_id);
+ return func.mCanCopy && mat_id.notNull();
+}
+
bool enable_object_open()
{
// Look for contents in root object, which is all the LLFloaterOpenObject
@@ -2845,37 +2907,42 @@ class LLObjectBuild : public view_listener_t
}
};
-void handle_object_edit()
+void update_camera()
{
- LLViewerParcelMgr::getInstance()->deselectLand();
+ LLViewerParcelMgr::getInstance()->deselectLand();
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
- {
- LLFloaterTools::sPreviousFocusOnAvatar = true;
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // always freeze camera in space, even if camera doesn't move
+ // so, for example, follow cam scripts can't affect you when in build mode
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
+ else
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ LLViewerObject* selected_objectp = selection->getFirstRootObject();
+ if (selected_objectp)
+ {
+ // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
+ gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver(30.f * DEG_TO_RAD);
+ gViewerWindow->moveCursorToCenter();
+ }
+ }
+ }
+}
+
+void handle_object_edit()
+{
+ update_camera();
- if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // always freeze camera in space, even if camera doesn't move
- // so, for example, follow cam scripts can't affect you when in build mode
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- }
- else
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- LLViewerObject* selected_objectp = selection->getFirstRootObject();
- if (selected_objectp)
- {
- // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
- gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- }
- }
-
LLFloaterReg::showInstance("build");
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -2889,6 +2956,28 @@ void handle_object_edit()
return;
}
+void handle_object_edit_gltf_material()
+{
+ if (!LLFloaterReg::instanceVisible("build"))
+ {
+ handle_object_edit(); // does update_camera();
+ }
+ else
+ {
+ update_camera();
+
+ LLViewerJoystick::getInstance()->moveObjects(true);
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+ }
+
+ LLMaterialEditor::loadLive();
+}
+
+void handle_object_save_gltf_material()
+{
+ LLMaterialEditor::loadObjectSave();
+}
+
void handle_attachment_edit(const LLUUID& inv_item_id)
{
if (isAgentAvatarValid())
@@ -3589,6 +3678,11 @@ bool my_profile_visible()
return floaterp && floaterp->isInVisibleChain();
}
+bool picks_tab_visible()
+{
+ return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
+}
+
bool enable_freeze_eject(const LLSD& avatar_id)
{
// Use avatar_id if available, otherwise default to right-click avatar
@@ -4169,23 +4263,9 @@ bool is_object_sittable()
}
}
-
// only works on pie menu
-void handle_object_sit_or_stand()
+void handle_object_sit(LLViewerObject *object, const LLVector3 &offset)
{
- LLPickInfo pick = LLToolPie::getInstance()->getPick();
- LLViewerObject *object = pick.getObject();;
- if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
- {
- return;
- }
-
- if (sitting_on_selection())
- {
- gAgent.standUp();
- return;
- }
-
// get object selection offset
if (object && object->getPCode() == LL_PCODE_VOLUME)
@@ -4197,12 +4277,42 @@ void handle_object_sit_or_stand()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, pick.mObjectOffset);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
object->getRegion()->sendReliableMessage();
}
}
+void handle_object_sit_or_stand()
+{
+ LLPickInfo pick = LLToolPie::getInstance()->getPick();
+ LLViewerObject *object = pick.getObject();
+ if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
+ {
+ return;
+ }
+
+ if (sitting_on_selection())
+ {
+ gAgent.standUp();
+ return;
+ }
+
+ handle_object_sit(object, pick.mObjectOffset);
+}
+
+void handle_object_sit(const LLUUID& object_id)
+{
+ LLViewerObject* obj = gObjectList.findObject(object_id);
+ if (!obj)
+ {
+ return;
+ }
+
+ LLVector3 offset(0, 0, 0);
+ handle_object_sit(obj, offset);
+}
+
void near_sit_down_point(BOOL success, void *)
{
if (success)
@@ -5298,12 +5408,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
{
bool returnValue = false;
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
- returnValue = (rebakeInstance->canRebakeRegion() &&
- (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available));
- }
+ if (LLNavigationBar::instanceExists())
+ {
+ returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
+ }
return returnValue;
}
};
@@ -6266,6 +6374,29 @@ class LLAvatarToggleMyProfile : public view_listener_t
}
};
+class LLAvatarTogglePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+ if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ else if (picks_tab_visible())
+ {
+ instance->closeFloater();
+ }
+ else
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ return true;
+ }
+};
+
class LLAvatarToggleSearch : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6337,6 +6468,24 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t
}
};
+class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar)
+ {
+ avatar->resetSkeleton(true);
+ }
+ else
+ {
+ gAgentAvatarp->resetSkeleton(true);
+ }
+ return true;
+ }
+};
+
+
class LLAvatarAddContact : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6718,6 +6867,15 @@ class LLShowAgentProfile : public view_listener_t
}
};
+class LLShowAgentProfilePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ return true;
+ }
+};
+
class LLToggleAgentProfile : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7964,6 +8122,18 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t
}
};
+class LLToolsSelectInvisibleObjects : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects");
+
+ gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val);
+
+ return true;
+ }
+};
+
class LLToolsSelectBySurrounding : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -8296,6 +8466,12 @@ void handle_cache_clear_immediately()
LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
}
+void handle_rebuild_reflection_probes()
+{
+ gPipeline.mReflectionMapManager.rebuild();
+}
+
+
void handle_web_content_test(const LLSD& param)
{
std::string url = param.asString();
@@ -9187,6 +9363,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
+ view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
@@ -9255,10 +9432,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
- view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
- view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
@@ -9355,6 +9528,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+ // Advanced > Cache
+ view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
+
// Advanced > Recorder
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
@@ -9365,8 +9541,10 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
@@ -9392,6 +9570,8 @@ void initialize_menus()
//Develop (clear cache immediately)
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
+ //Develop (override environment map)
+ commit.add("Develop.RebuildReflectionProbes", boost::bind(&handle_rebuild_reflection_probes));
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
@@ -9439,11 +9619,14 @@ void initialize_menus()
enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
+ view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
+ view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
+ enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
@@ -9453,6 +9636,7 @@ void initialize_menus()
// Object pie menu
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
+ commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
@@ -9467,10 +9651,15 @@ void initialize_menus()
commit.add("Object.Buy", boost::bind(&handle_buy));
commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
+ commit.add("Object.SaveGLTFMaterial", boost::bind(&handle_object_save_gltf_material));
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
+ enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
+ enable.add("Object.EnableSaveGLTFMaterial", boost::bind(&enable_object_save_gltf_material));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
@@ -9519,6 +9708,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 36b6971c81..0673652e61 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -90,6 +90,8 @@ void handle_gestures(void*);
void handle_sit_down(void*);
void handle_object_build(void*);
void handle_object_touch();
+bool enable_object_edit_gltf_material();
+bool enable_object_save_gltf_material();
bool enable_object_open();
void handle_object_open();
@@ -108,6 +110,8 @@ void handle_zoom_to_object(LLUUID object_id);
void handle_object_return();
void handle_object_delete();
void handle_object_edit();
+void handle_object_edit_gltf_material();
+void handle_object_save_gltf_material();
void handle_attachment_edit(const LLUUID& inv_item_id);
void handle_attachment_touch(const LLUUID& inv_item_id);
@@ -135,6 +139,7 @@ void handle_save_snapshot(void *);
void handle_toggle_flycam();
void handle_object_sit_or_stand();
+void handle_object_sit(const LLUUID& object_id);
void handle_give_money_dialog();
bool enable_pay_object();
bool enable_buy_object();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 28ff69eaf5..ffa2ce865e 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -37,6 +37,7 @@
#include "llbuycurrencyhtml.h"
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
+#include "llmaterialeditor.h"
#include "llfloatersnapshot.h"
#include "llfloateroutfitsnapshot.h"
#include "llimage.h"
@@ -101,6 +102,20 @@ class LLFileEnableUploadModel : public view_listener_t
}
};
+class LLFileEnableUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::findInstance("material_editor");
+ if (me && me->isShown())
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
class LLMeshEnabled : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -234,6 +249,16 @@ LLFilePickerReplyThread::~LLFilePickerReplyThread()
delete mFailureSignal;
}
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, get_multiple, failure_cb))->getFile();
+}
+
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ESaveFilter filter, const std::string & proposed_name, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, proposed_name, failure_cb))->getFile();
+}
+
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
if (filenames.empty())
@@ -255,13 +280,13 @@ void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
: LLFilePickerThread(filter, get_multiple),
- mPlugin(plugin->getSharedPrt())
+ mPlugin(plugin->getSharedPtr())
{
}
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
: LLFilePickerThread(filter, proposed_name),
- mPlugin(plugin->getSharedPrt())
+ mPlugin(plugin->getSharedPtr())
{
}
@@ -277,14 +302,12 @@ void LLMediaFilePicker::notify(const std::vector<std::string>& filenames)
static std::string SOUND_EXTENSIONS = "wav";
static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png";
static std::string ANIM_EXTENSIONS = "bvh anim";
-#ifdef _CORY_TESTING
-static std::string GEOMETRY_EXTENSIONS = "slg";
-#endif
static std::string XML_EXTENSIONS = "xml";
static std::string SLOBJECT_EXTENSIONS = "slobject";
#endif
static std::string ALL_FILE_EXTENSIONS = "*.*";
static std::string MODEL_EXTENSIONS = "dae";
+static std::string MATERIAL_EXTENSIONS = "gltf glb";
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
{
@@ -301,10 +324,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
return SLOBJECT_EXTENSIONS;
case LLFilePicker::FFLOAD_MODEL:
return MODEL_EXTENSIONS;
-#ifdef _CORY_TESTING
- case LLFilePicker::FFLOAD_GEOMETRY:
- return GEOMETRY_EXTENSIONS;
-#endif
+ case LLFilePicker::FFLOAD_MATERIAL:
+ return MATERIAL_EXTENSIONS;
case LLFilePicker::FFLOAD_XML:
return XML_EXTENSIONS;
case LLFilePicker::FFLOAD_ALL:
@@ -560,7 +581,7 @@ class LLFileUploadImage : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false);
return true;
}
};
@@ -573,7 +594,16 @@ class LLFileUploadModel : public view_listener_t
return TRUE;
}
};
-
+
+class LLFileUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLMaterialEditor::importMaterial();
+ return TRUE;
+ }
+};
+
class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -582,7 +612,7 @@ class LLFileUploadSound : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false);
return true;
}
};
@@ -595,7 +625,7 @@ class LLFileUploadAnim : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false);
return true;
}
};
@@ -608,7 +638,7 @@ class LLFileUploadBulk : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true);
return true;
}
};
@@ -1104,6 +1134,7 @@ void init_menu_file()
view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
+ view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial");
view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index beeac418d9..5c2caf9c51 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -115,14 +115,18 @@ class LLFilePickerReplyThread : public LLFilePickerThread
public:
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
-
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- ~LLFilePickerReplyThread();
+
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
virtual void notify(const std::vector<std::string>& filenames);
private:
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ ~LLFilePickerReplyThread();
+
+private:
LLFilePicker::ELoadFilter mLoadFilter;
LLFilePicker::ESaveFilter mSaveFilter;
file_picked_signal_t* mFilePickedSignal;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a886303563..e96047df14 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -33,6 +33,7 @@
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO HACK
#include "lleventtimer.h"
+#include "llfloatercreatelandmark.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llfollowcamparams.h"
@@ -122,6 +123,7 @@
#include "llexperiencecache.h"
#include "llexperiencecache.h"
+#include "lluiusage.h"
extern void on_new_message(const LLSD& msg);
@@ -261,6 +263,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
{
case 0:
{
+ LLUIUsage::instance().logCommand("Agent.AcceptFriendship");
// accept
LLAvatarTracker::formFriendship(payload["from_id"]);
@@ -303,6 +306,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
// fall-through
case 2: // Send IM - decline and start IM session
{
+ LLUIUsage::instance().logCommand("Agent.DeclineFriendship");
// decline
// We no longer notify other viewers, but we DO still send
// the rejection to the simulator to delete the pending userop.
@@ -833,6 +837,11 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep
EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE;
+ if (accept_invite)
+ {
+ LLUIUsage::instance().logCommand("Group.Join");
+ }
+
send_improved_im(group_id,
std::string("name"),
std::string("message"),
@@ -1414,7 +1423,8 @@ bool check_asset_previewable(const LLAssetType::EType asset_type)
(asset_type == LLAssetType::AT_TEXTURE) ||
(asset_type == LLAssetType::AT_ANIMATION) ||
(asset_type == LLAssetType::AT_SCRIPT) ||
- (asset_type == LLAssetType::AT_SOUND);
+ (asset_type == LLAssetType::AT_SOUND) ||
+ (asset_type == LLAssetType::AT_MATERIAL);
}
void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name)
@@ -1519,6 +1529,9 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
case LLAssetType::AT_SOUND:
LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
break;
+ case LLAssetType::AT_MATERIAL:
+ LLFloaterReg::showInstance("material editor", LLSD(obj_id), take_focus);
+ break;
default:
LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL;
break;
@@ -1560,6 +1573,17 @@ bool highlight_offered_object(const LLUUID& obj_id)
}
}
+ if (obj->getType() == LLAssetType::AT_LANDMARK)
+ {
+ LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark");
+ if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id)
+ {
+ // LLFloaterCreateLandmark is supposed to handle this,
+ // keep landmark creation floater at the front
+ return false;
+ }
+ }
+
return true;
}
@@ -5805,15 +5829,15 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
continue;
- if (script_perm.question == "JoinAnExperience")
- { // Some experience only permissions do not have an explicit permission bit. Add them here.
- script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n";
+ if (LLTrans::getString(script_perm.question).empty())
+ {
+ continue;
}
script_question += " " + LLTrans::getString(script_perm.question) + "\n";
}
}
-
+
args["QUESTIONS"] = script_question;
if (known_questions != questions)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a95636ff23..ac76ad7272 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -107,6 +107,7 @@
#include "llcleanup.h"
#include "llcallstack.h"
#include "llmeshrepository.h"
+#include "llgltfmateriallist.h"
#include "llgl.h"
//#define DEBUG_UPDATE_TYPE
@@ -246,6 +247,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
res = NULL; break;
}
+
return res;
}
@@ -259,7 +261,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mTEImages(NULL),
mTENormalMaps(NULL),
mTESpecularMaps(NULL),
- mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
mPhysicsShapeType(0),
@@ -343,6 +344,13 @@ LLViewerObject::~LLViewerObject()
{
deleteTEImages();
+ // unhook from reflection probe manager
+ if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe->mViewerObject = nullptr;
+ mReflectionProbe = nullptr;
+ }
+
if(mInventory)
{
mInventory->clear(); // will deref and delete entries
@@ -356,6 +364,13 @@ LLViewerObject::~LLViewerObject()
mPartSourcep = NULL;
}
+ if (mText)
+ {
+ // something recovered LLHUDText when object was already dead
+ mText->markDead();
+ mText = NULL;
+ }
+
// Delete memory associated with extra parameters.
std::map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
@@ -2457,11 +2472,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
needs_refresh = needs_refresh || child->mUserSelected;
}
+ static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);
if (needs_refresh)
{
LLSelectMgr::getInstance()->updateSelectionCenter();
dialog_refresh_all();
- }
+ }
+ else if (allow_select_avatar && asAvatar())
+ {
+ // Override any avatar position updates received
+ // Works only if avatar was repositioned using build
+ // tools and build floater is visible
+ LLSelectMgr::getInstance()->overrideAvatarUpdates();
+ }
// Mark update time as approx. now, with the ping delay.
@@ -3471,11 +3494,11 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
++mExpectedInventorySerialNum;
}
-bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
+bool LLViewerObject::isAssetInInventory(LLViewerInventoryItem* item)
{
bool result = false;
- if (item && LLAssetType::AT_TEXTURE == item->getType())
+ if (item)
{
std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
@@ -3489,13 +3512,27 @@ bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
return result;
}
-void LLViewerObject::updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
+void LLViewerObject::updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
{
- if (item && !isTextureInInventory(item))
- {
- mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
- updateInventory(item, key, is_new);
- }
+ if (!item)
+ {
+ return;
+ }
+ if (LLAssetType::AT_TEXTURE != item->getType()
+ && LLAssetType::AT_MATERIAL != item->getType())
+ {
+ // Not supported
+ return;
+ }
+
+ if (isAssetInInventory(item))
+ {
+ // already there
+ return;
+ }
+
+ mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+ updateInventory(item, key, is_new);
}
void LLViewerObject::updateInventory(
@@ -4566,6 +4603,7 @@ BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVecto
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -4852,23 +4890,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID&
}
}
-void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
+
+void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry)
{
- LLUUID old_image_id;
- if (getTE(te))
- {
- old_image_id = getTE(te)->getID();
- }
-
- LLPrimitive::setTE(te, texture_entry);
+ LLUUID old_image_id;
+ if (getTE(te))
+ {
+ old_image_id = getTE(te)->getID();
+ }
- const LLUUID& image_id = getTE(te)->getID();
- LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
- mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLPrimitive::setTE(te, texture_entry);
-
- updateAvatarMeshVisibility(image_id,old_image_id);
+ const LLUUID& image_id = getTE(te)->getID();
+ LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
+ mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ updateAvatarMeshVisibility(image_id, old_image_id);
+
+ updateTEMaterialTextures(te);
+}
+void LLViewerObject::updateTEMaterialTextures(U8 te)
+{
if (getTE(te)->getMaterialParams().notNull())
{
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
@@ -4877,6 +4920,48 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
}
+
+ LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
+ LLUUID mat_id = getRenderMaterialID(te);
+ if (mat == nullptr && mat_id.notNull())
+ {
+ mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id);
+ getTE(te)->setGLTFMaterial(mat);
+ }
+ else if (mat_id.isNull() && mat != nullptr)
+ {
+ mat = nullptr;
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+
+ auto fetch_texture = [this](const LLUUID& id)
+ {
+ LLViewerFetchedTexture* img = nullptr;
+ if (id.notNull())
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ // TODO -- fall back to LLTextureEntry::mGLTFRenderMaterial when overriding with baked texture
+ LLViewerTexture* viewerTexture = getBakedTextureForMagicId(id);
+ img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : nullptr;
+ }
+ else
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
+ img->addTextureStats(64.f * 64.f, TRUE);
+ }
+ }
+
+ return img;
+ };
+
+ if (mat != nullptr)
+ {
+ mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId);
+ mat->mNormalTexture = fetch_texture(mat->mNormalId);
+ mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId);
+ mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId);
+ }
}
void LLViewerObject::refreshBakeTexture()
@@ -5231,10 +5316,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
- refreshMaterials();
return retval;
}
+S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
+{
+ S32 retval = TEM_CHANGE_NONE;
+
+ LLTextureEntry* tep = getTE(te);
+ if (!tep)
+ { // this could happen if the object is not fully formed yet
+ // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later
+ return retval;
+ }
+
+ LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
+
+ tep->setGLTFMaterialOverride(override_mat);
+
+ // if override mat exists, we must also have a source mat
+ llassert(override_mat ? bool(src_mat) : true);
+
+ if (override_mat && src_mat)
+ {
+ LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
+ render_mat->applyOverride(*override_mat);
+ tep->setGLTFRenderMaterial(render_mat);
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ else if (tep->setGLTFRenderMaterial(nullptr))
+ {
+ retval = TEM_CHANGE_TEXTURE;
+ }
+
+ return retval;
+}
+
void LLViewerObject::refreshMaterials()
{
setChanged(TEXTURE);
@@ -5417,7 +5534,6 @@ void LLViewerObject::fitFaceTexture(const U8 face)
LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
}
-
LLBBox LLViewerObject::getBoundingBoxAgent() const
{
LLVector3 position_agent;
@@ -5502,18 +5618,6 @@ S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
return count;
}
-
-void LLViewerObject::setCanSelect(BOOL canSelect)
-{
- mbCanSelect = canSelect;
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->mbCanSelect = canSelect;
- }
-}
-
void LLViewerObject::setDebugText(const std::string &utf8text)
{
if (utf8text.empty() && !mText)
@@ -6017,6 +6121,16 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLExtendedMeshParams();
break;
}
+ case LLNetworkData::PARAMS_RENDER_MATERIAL:
+ {
+ new_block = new LLRenderMaterialParams();
+ break;
+ }
+ case LLNetworkData::PARAMS_REFLECTION_PROBE:
+ {
+ new_block = new LLReflectionProbeParams();
+ break;
+ }
default:
{
LL_INFOS() << "Unknown param type." << LL_ENDL;
@@ -6160,6 +6274,14 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL;
}
}
+ else
+ {
+ if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
+ {
+ const LLRenderMaterialParams* params = in_use ? (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL) : nullptr;
+ setRenderMaterialIDs(params, local_origin);
+ }
+ }
}
void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
@@ -6958,6 +7080,167 @@ LLVOAvatar* LLViewerObject::getAvatar() const
return NULL;
}
+bool LLViewerObject::hasRenderMaterialParams() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
+}
+
+void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
+{
+ bool had_materials = hasRenderMaterialParams();
+
+ if (had_materials != has_materials)
+ {
+ if (has_materials)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
+ }
+ }
+}
+
+const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
+{
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ return param_block->getMaterial(te);
+ }
+
+ return LLUUID::null;
+}
+
+void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id, bool update_server)
+{
+ if (id.notNull())
+ {
+ getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id));
+
+ if (!hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ // but do not update server to avoid race conditions
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = true;
+ }
+ }
+ }
+ else
+ {
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ param_block->setMaterial(te, id);
+
+ if (param_block->isEmpty())
+ { // might be empty if id is null
+ if (hasRenderMaterialParams())
+ {
+ if (update_server)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
+ }
+ else
+ {
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = false;
+ }
+ }
+ }
+ }
+ else if (update_server)
+ {
+ parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ if (!hasRenderMaterialParams())
+ {
+ // make sure param section exists
+ // but do not update server to avoid race conditions
+ ExtraParameter* param = getExtraParameterEntryCreate(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param)
+ {
+ param->in_use = true;
+ }
+ }
+ }
+
+ LLRenderMaterialParams* param_block = nullptr;
+ if (hasRenderMaterialParams())
+ {
+ param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ }
+
+ LLGLTFMaterial* material = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id);
+ const S32 num_tes = llmin((S32)getNumTEs(), (S32)getNumFaces());
+
+ for (S32 te = 0; te < num_tes; te++)
+ {
+ getTE(te)->setGLTFMaterial(material);
+
+ if (param_block)
+ {
+ param_block->setMaterial(te, id);
+ }
+ }
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+
+ if (param_block)
+ {
+ if (param_block->isEmpty())
+ {
+ setHasRenderMaterialParams(false);
+ }
+ else
+ {
+ parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true);
+ }
+ }
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin)
+{
+ if (!local_origin)
+ {
+ const S32 num_tes = llmin((S32)getNumTEs(), (S32)getNumFaces()); // avatars have TEs but no faces
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ const LLUUID& id = material_params ? material_params->getMaterial(te) : LLUUID::null;
+ if (id.notNull())
+ {
+ getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id));
+ setHasRenderMaterialParams(true);
+ }
+ else
+ {
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+ }
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+ }
+}
class ObjectPhysicsProperties : public LLHTTPNode
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index bef8e3e7e3..31e82545ec 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -43,6 +43,7 @@
#include "llvertexbuffer.h"
#include "llbbox.h"
#include "llrigginginfo.h"
+#include "llreflectionmap.h"
class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
@@ -178,6 +179,14 @@ public:
const std::string& getAttachmentItemName() const;
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
+
+ bool hasRenderMaterialParams() const;
+ void setHasRenderMaterialParams(bool has_params);
+
+ const LLUUID& getRenderMaterialID(U8 te) const;
+ void setRenderMaterialID(U8 te, const LLUUID& id, bool update_server = true);
+ void setRenderMaterialIDs(const LLUUID& id);
+
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
@@ -199,6 +208,7 @@ public:
// Graphical stuff for objects - maybe broken out into render class later?
virtual void updateTextures();
+ virtual void faceMappingChanged() {}
virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
virtual LLDrawable* createDrawable(LLPipeline *pipeline);
@@ -210,6 +220,7 @@ public:
F32 getRotTime() { return mRotTime; }
private:
void resetRotTime();
+ void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
public:
void resetRot();
void applyAngularVelocity(F32 dt);
@@ -238,6 +249,7 @@ public:
virtual BOOL isMesh() const { return FALSE; }
virtual BOOL isRiggedMesh() const { return FALSE; }
virtual BOOL hasLightTexture() const { return FALSE; }
+ virtual BOOL isReflectionProbe() const { return FALSE; }
// This method returns true if the object is over land owned by
// the agent, one of its groups, or it encroaches and
@@ -279,6 +291,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -318,6 +331,7 @@ public:
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
+ void updateTEMaterialTextures(U8 te);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
@@ -342,6 +356,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);
+ virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds
// of VBs etc when materials updates require changes.
@@ -356,7 +371,7 @@ public:
LLViewerTexture *getTEImage(const U8 te) const;
LLViewerTexture *getTENormalMap(const U8 te) const;
LLViewerTexture *getTESpecularMap(const U8 te) const;
-
+
bool isImageAlphaBlended(const U8 te) const;
void fitFaceTexture(const U8 face);
@@ -420,8 +435,6 @@ public:
void sendMaterialUpdate() const;
- void setCanSelect(BOOL canSelect);
-
void setDebugText(const std::string &utf8text);
void initHudText();
void restoreHudText();
@@ -472,7 +485,7 @@ public:
// manager until we have better iterators.
void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
- void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
// Get content except for root category
@@ -481,8 +494,6 @@ public:
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
S16 getInventorySerial() const { return mInventorySerialNum; }
- bool isTextureInInventory(LLViewerInventoryItem* item);
-
// These functions does viewer-side only object inventory modifications
void updateViewerInventoryAsset(
const LLViewerInventoryItem* item,
@@ -611,6 +622,8 @@ public:
std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
+ bool isAssetInInventory(LLViewerInventoryItem* item);
+
ExtraParameter* createNewParameterEntry(U16 param_type);
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
@@ -674,10 +687,10 @@ public:
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
-
- // Selection, picking and rendering variables
- U32 mGLName; // GL "name" used by selection code
- BOOL mbCanSelect; // true if user can select this object by clicking
+
+ // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
+ // can likely be factored out
+ BOOL mbCanSelect;
private:
// Grabbed from UPDATE_FLAGS
@@ -845,7 +858,7 @@ protected:
F32 mLinksetCost;
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
-
+
bool mCostStale;
mutable bool mPhysicsShapeUnknown;
@@ -904,6 +917,11 @@ private:
LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
EObjectUpdateType mLastUpdateType;
BOOL mLastUpdateCached;
+
+public:
+ // reflection probe state
+ bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed
};
///////////////////
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 0e585f13fc..768b4f425b 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -72,7 +72,7 @@
#ifdef LL_USESYSTEMLIBS
#include <zlib.h>
#else
-#include "zlib/zlib.h"
+#include "zlib-ng/zlib.h"
#endif
#include "object_flags.h"
@@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if(update_cache)
{
- objectp = regionp->updateCacheEntry(local_id, objectp, update_type);
+ //update object cache if the object receives a full-update or terse update
+ objectp = regionp->updateCacheEntry(local_id, objectp);
}
// This looks like it will break if the local_id of the object doesn't change
@@ -1339,38 +1340,13 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
}
// Don't clean up mObject references, these will be cleaned up more efficiently later!
- // Also, not cleaned up
- removeDrawable(objectp->mDrawable);
-
+
if(new_dead_object)
{
mNumDeadObjects++;
}
}
-void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
- if (!drawablep)
- {
- return;
- }
-
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i) ;
- if(facep)
- {
- LLViewerObject* objectp = facep->getViewerObject();
- if(objectp)
- {
- mSelectPickList.erase(objectp);
- }
- }
- }
-}
-
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
{
// Don't ever kill gAgentAvatarp, just force it to the agent's region
@@ -1836,146 +1812,6 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
{
}
-void LLViewerObjectList::generatePickList(LLCamera &camera)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
- LLViewerObject *objectp;
- S32 i;
- // Reset all of the GL names to zero.
- for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
- {
- (*iter)->mGLName = 0;
- }
-
- mSelectPickList.clear();
-
- std::vector<LLDrawable*> pick_drawables;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->cull(camera, &pick_drawables, TRUE);
- }
- }
- }
-
- for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
- iter != pick_drawables.end(); iter++)
- {
- LLDrawable* drawablep = *iter;
- if( !drawablep )
- continue;
-
- LLViewerObject* last_objectp = NULL;
- for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
- {
- LLFace * facep = drawablep->getFace(face_num);
- if (!facep) continue;
-
- LLViewerObject* objectp = facep->getViewerObject();
-
- if (objectp && objectp != last_objectp)
- {
- mSelectPickList.insert(objectp);
- last_objectp = objectp;
- }
- }
- }
-
- LLHUDNameTag::addPickable(mSelectPickList);
-
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- objectp = (LLVOAvatar*) *iter;
- if (!objectp->isDead())
- {
- if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
- {
- mSelectPickList.insert(objectp);
- }
- }
- }
-
- // add all hud objects to pick list
- if (isAgentAvatarValid())
- {
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getIsHUDAttachment())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject* attached_object = attachment_iter->get())
- {
- mSelectPickList.insert(attached_object);
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (childp)
- {
- mSelectPickList.insert(childp);
- }
- }
- }
- }
- }
- }
- }
-
- S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();
-
- if (num_pickables != 0)
- {
- S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;
-
- std::set<LLViewerObject*>::iterator pick_it;
- i = 0;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
- {
- LLViewerObject* objp = (*pick_it);
- if (!objp || objp->isDead() || !objp->mbCanSelect)
- {
- mSelectPickList.erase(pick_it++);
- continue;
- }
-
- objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
- i++;
- ++pick_it;
- }
-
- LLHUDIcon::generatePickIDs(i * step, step);
- }
-}
-
-LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
-{
- std::set<LLViewerObject*>::iterator pick_it;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end(); ++pick_it)
- {
- if ((*pick_it)->mGLName == object_id)
- {
- return (*pick_it);
- }
- }
- return NULL;
-}
-
void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
const std::string &string,
const LLColor4 &color,
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 72b2b99004..f2cba8c259 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -77,7 +77,6 @@ public:
BOOL killObject(LLViewerObject *objectp);
void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region.
void killAllObjects();
- void removeDrawable(LLDrawable* drawablep);
void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list.
@@ -129,11 +128,6 @@ public:
void updateAvatarVisibility();
- // Selection related stuff
- void generatePickList(LLCamera &camera);
-
- LLViewerObject *getSelectedObject(const U32 object_id);
-
inline S32 getNumObjects() { return (S32) mObjects.size(); }
inline S32 getNumActiveObjects() { return (S32) mActiveObjects.size(); }
@@ -226,8 +220,6 @@ protected:
static std::map<U64, LLUUID> sIndexAndLocalIDToUUID;
- std::set<LLViewerObject *> mSelectPickList;
-
friend class LLViewerObject;
private:
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 12624ec3a2..1f16161780 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -800,7 +800,7 @@ U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName()
{
//seed 1024 query names into the free query pool
GLuint queries[1024];
- glGenQueriesARB(1024, queries);
+ glGenQueries(1024, queries);
for (int i = 0; i < 1024; ++i)
{
sFreeQueries.push(queries[i]);
@@ -917,15 +917,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr
void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
{
- if (gGLManager.mHasOcclusionQuery)
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
{
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
+ if (mOcclusionQuery[i])
{
- if (mOcclusionQuery[i])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
}
}
}
@@ -948,6 +945,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionStateDiff setter(state);
setter.traverse(mOctreeNode);
@@ -955,6 +953,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionState setter(state);
setter.traverse(mOctreeNode);
@@ -1024,6 +1023,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionStateDiff clearer(state);
clearer.traverse(mOctreeNode);
@@ -1031,6 +1031,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionState clearer(state);
clearer.traverse(mOctreeNode);
@@ -1125,7 +1126,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint available;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available);
}
if (available)
@@ -1133,7 +1134,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result);
}
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1168,7 +1169,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{ //check occlusion has been issued for occluded node that has not had a query issued
assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ //clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
}
@@ -1193,7 +1194,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
OCCLUSION_FUDGE_Z = 1.;
}
- // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, bounds))
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail");
@@ -1217,17 +1217,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// Depth clamp all water to avoid it being culled as a result of being
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
- bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
- (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
+ bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
- LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
+ LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
-#if !LL_DARWIN
- U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
-#else
- U32 mode = GL_SAMPLES_PASSED_ARB;
-#endif
+ U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED;
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1246,7 +1241,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
//get an occlusion query that hasn't been used in awhile
releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ glBeginQuery(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -1288,7 +1283,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
{
LL_PROFILE_ZONE_NAMED("glEndQuery");
- glEndQueryARB(mode);
+ glEndQuery(mode);
}
}
}
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index e6974b0f84..7666062f99 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -45,11 +45,11 @@ class LLViewerOctreeGroup;
class LLViewerOctreeEntry;
class LLViewerOctreePartition;
-typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
-typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
-typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
-typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
-typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
+typedef LLOctreeListener<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeListener;
+typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
+typedef LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeNode;
+typedef LLOctreeRoot<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeRoot;
+typedef LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeTraveler;
#if LL_OCTREE_PARANOIA_CHECK
#define assert_octree_valid(x) x->validate()
@@ -179,7 +179,7 @@ protected:
//defines an octree group for an octree node, which contains multiple entries.
//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
-: public LLOctreeListener<LLViewerOctreeEntry>
+: public OctreeListener
{
LL_ALIGN_NEW
friend class LLViewerOctreeCull;
@@ -198,8 +198,8 @@ public:
};
public:
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+ typedef OctreeNode::element_iter element_iter;
+ typedef OctreeNode::element_list element_list;
LLViewerOctreeGroup(OctreeNode* node);
LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs)
@@ -245,7 +245,6 @@ public:
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
//octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index e69b0347f8..75eb16c085 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
BOOL region_allow_environment_override = true;
S32 parcel_environment_version = 0;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
+ U32 extended_flags = 0; //obscure MOAP
S32 other_clean_time = 0;
@@ -1591,6 +1592,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
+ // *TODO: Does it really make sense to set the agent parcel to this
+ // parcel if the client doesn't know what kind of parcel data this is?
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
@@ -1642,6 +1645,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
+ if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags))
+ {
+ msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags);
+ }
+
if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))
{
msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version);
@@ -1698,6 +1706,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);
parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+ parcel->setObscureMOAP((bool)extended_flags);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1879,8 +1889,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- // Check for video
- LLViewerParcelMedia::getInstance()->update(parcel);
+ if (gNonInteractive)
+ {
+ return;
+ }
+
+ // Check for video
+ LLViewerParcelMedia::getInstance()->update(parcel);
// Then check for music
if (gAudiop)
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 02f7bbeed8..785c84c38d 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -264,7 +264,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column];
+ return parcelFlags(row, column, PARCEL_SOUND_LOCAL);
}
U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
@@ -278,12 +278,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return parcelLineFlags(row, column);
+ return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
}
U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
{
- U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
- if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+ return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
+}
+
+U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const
+{
+ if (row >= mParcelGridsPerEdge
+ || col >= mParcelGridsPerEdge
+ || row < 0
+ || col < 0)
{
LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
return flags;
@@ -908,8 +915,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Always fudge a little vertically.
pull_toward_camera.mV[VZ] += 0.01f;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
@@ -1014,7 +1021,66 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
}
- gGL.popMatrix();
+ gGL.popMatrix();
return drawn;
}
+
+// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
+void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom)
+{
+ gGL.begin(LLRender::LINES);
+
+ if (has_left)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(left, top);
+ }
+ if (has_bottom)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(right, bottom);
+ }
+
+ gGL.end();
+}
+
+void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (!mOwnership)
+ {
+ return;
+ }
+ if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ return;
+ }
+
+ LLVector3 origin_agent = mRegion->getOriginAgent();
+ LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
+ F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter;
+ F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter;
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glLineWidth(1.0f);
+ gGL.color4fv(parcel_outline_color);
+ for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ {
+ const F32 bottom = region_bottom + (i * map_parcel_width);
+ const F32 top = bottom + map_parcel_width;
+ for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ {
+ const F32 left = region_left + (j * map_parcel_width);
+ const F32 right = left + map_parcel_width;
+ const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE;
+ const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j];
+ // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a
+ // 2D map
+ const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE));
+ const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE));
+ grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index e30dbf17b3..c466cc3b6b 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -69,6 +69,7 @@ public:
// Returns the number of vertices drawn
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -82,12 +83,14 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
U8 ownership(S32 row, S32 col) const
- { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; }
+ { return parcelFlags(row, col, (U8)0x7); }
+
+ U8 parcelFlags(S32 row, S32 col, U8 flags) const;
void addPropertyLine(std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 67ad72e997..36d8fffa7c 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -95,8 +95,6 @@
// The server only keeps our pending agent info for 60 seconds.
// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -178,7 +176,6 @@ public:
mCompositionp(NULL),
mEventPoll(NULL),
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
- mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
mSeedCapAttempts(0),
mHttpResponderID(0),
mLastCameraUpdate(0),
@@ -231,7 +228,6 @@ public:
LLEventPoll* mEventPoll;
S32 mSeedCapMaxAttempts;
- S32 mSeedCapMaxAttemptsBeforeLogin;
S32 mSeedCapAttempts;
S32 mHttpResponderID;
@@ -266,14 +262,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return;
}
- LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
@@ -287,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ regionp->setCapabilitiesError();
return; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
- // After a few attempts, continue login. But keep trying to get the caps:
- if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts)
{
// *TODO: Give a user pop-up about this error?
@@ -321,7 +310,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
regionp = NULL;
impl = NULL;
- world_inst = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
if (STATE_WORLD_INIT > LLStartUp::getStartupState())
@@ -332,17 +320,17 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (LLApp::isExiting() || gDisconnected)
{
+ LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;
return;
}
- world_inst = LLWorld::getInstance();
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
@@ -351,14 +339,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
impl = regionp->getRegionImplNC();
- ++impl->mSeedCapAttempts;
-
- if (id != impl->mHttpResponderID) // region is no longer referring to this request
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
- // setup for retry.
- continue;
- }
+ ++(impl->mSeedCapAttempts);
if (!result.isMap() || result.has("error"))
{
@@ -379,6 +360,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
// remove the http_result from the llsd
result.erase("http_result");
+ if (id != impl->mHttpResponderID) // region is no longer referring to this request
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
LLSD::map_const_iterator iter;
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
{
@@ -396,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
<< " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
break;
}
while (true);
@@ -444,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ if (regionp->getCapability("Seed").empty())
+ {
+ // initial attempt failed to get this cap as well
+ regionp->setCapabilitiesError();
+ }
break; // this error condition is not recoverable.
}
@@ -645,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheLoaded(FALSE),
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
- mCapabilitiesReceived(false),
+ mCapabilitiesState(CAPABILITIES_STATE_INIT),
mSimulatorFeaturesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
@@ -1080,6 +1068,15 @@ S32 LLViewerRegion::renderPropertyLines()
}
}
+void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color);
+ }
+}
+
+
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
@@ -1245,6 +1242,47 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
return mImpl ? mImpl->mVisibleGroups.size() : 0;
}
+void LLViewerRegion::updateReflectionProbes()
+{
+#if 1
+ const F32 probe_spacing = 32.f;
+ const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
+ const F32 hover_height = 2.f;
+
+ F32 start = probe_spacing * 0.5f;
+
+ U32 grid_width = REGION_WIDTH_METERS / probe_spacing;
+
+ mReflectionMaps.resize(grid_width * grid_width);
+
+ F32 water_height = getWaterHeight();
+ LLVector3 origin = getOriginAgent();
+
+ for (U32 i = 0; i < grid_width; ++i)
+ {
+ F32 x = i * probe_spacing + start;
+ for (U32 j = 0; j < grid_width; ++j)
+ {
+ F32 y = j * probe_spacing + start;
+
+ U32 idx = i * grid_width + j;
+
+ if (mReflectionMaps[idx].isNull())
+ {
+ mReflectionMaps[idx] = gPipeline.mReflectionMapManager.addProbe();
+ }
+
+ LLVector3 probe_origin = LLVector3(x,y, llmax(water_height, mImpl->mLandp->resolveHeightRegion(x,y)));
+ probe_origin.mV[2] += hover_height;
+ probe_origin += origin;
+
+ mReflectionMaps[idx]->mOrigin.load3(probe_origin.mV);
+ mReflectionMaps[idx]->mRadius = probe_radius;
+ }
+ }
+#endif
+}
+
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
{
if(!sVOCacheCullingEnabled)
@@ -1820,13 +1858,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//update object cache if the object receives a full-update or terse update
//update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL
-LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type)
+LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)
{
- if(objectp && update_type != (U32)OUT_TERSE_IMPROVED)
- {
- return objectp; //no need to access cache
- }
-
LLVOCacheEntry* entry = getCacheEntry(local_id);
if (!entry)
{
@@ -1838,11 +1871,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o
objectp = addNewObject(entry);
}
- //remove from cache if terse update
- if(update_type == (U32)OUT_TERSE_IMPROVED)
- {
- killCacheEntry(entry, true);
- }
+ //remove from cache.
+ killCacheEntry(entry, true);
return objectp;
}
@@ -2302,6 +2332,11 @@ void LLViewerRegion::requestSimulatorFeatures()
std::string coroname =
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle()));
+
+ // requestSimulatorFeatures can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3002,6 +3037,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AcceptFriendship");
capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
capabilityNames.append("AgentPreferences");
+ capabilityNames.append("AgentProfile");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
@@ -3055,11 +3091,13 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("ModifyMaterialParams");
capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ObjectAnimation");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
+ capabilityNames.append("ObjectNavMeshProperties");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
@@ -3095,6 +3133,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
+ capabilityNames.append("UploadAgentProfileImage");
+ capabilityNames.append("UpdateMaterialAgentInventory");
+ capabilityNames.append("UpdateMaterialTaskInventory");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
@@ -3120,6 +3161,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle()));
+
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
return;
}
@@ -3133,6 +3180,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle()));
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3254,12 +3306,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
bool LLViewerRegion::capabilitiesReceived() const
{
- return mCapabilitiesReceived;
+ return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
+}
+
+bool LLViewerRegion::capabilitiesError() const
+{
+ return mCapabilitiesState == CAPABILITIES_STATE_ERROR;
}
void LLViewerRegion::setCapabilitiesReceived(bool received)
{
- mCapabilitiesReceived = received;
+ mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
// Tell interested parties that we've received capabilities,
// so that they can safely use getCapability().
@@ -3274,6 +3331,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
}
}
+void LLViewerRegion::setCapabilitiesError()
+{
+ mCapabilitiesState = CAPABILITIES_STATE_ERROR;
+}
+
boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
return mCapabilitiesReceivedSignal.connect(cb);
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index fcbf56c81f..8b27004f1d 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -41,6 +41,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llframetimer.h"
+#include "llreflectionmap.h"
// Surface id's
#define LAND 1
@@ -154,6 +155,8 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+
// Call this whenever you change the height data in the region.
// (Automatically called by LLSurfacePatch's update routine)
@@ -268,7 +271,9 @@ public:
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;
+ bool capabilitiesError() const;
void setCapabilitiesReceived(bool received);
+ void setCapabilitiesError();
boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
static bool isSpecialCapabilityName(const std::string &name);
@@ -352,7 +357,7 @@ public:
void requestCacheMisses();
void addCacheMissFull(const U32 local_id);
//update object cache if the object receives a full-update or terse update
- LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type);
+ LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
void findOrphans(U32 parent_id);
void clearCachedVisibleObjects();
void dumpCache();
@@ -397,6 +402,9 @@ public:
static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
+ // rebuild reflection probe list
+ void updateReflectionProbes();
+
private:
void addToVOCacheTree(LLVOCacheEntry* entry);
LLViewerObject* addNewObject(LLVOCacheEntry* entry);
@@ -527,12 +535,20 @@ private:
BOOL mCacheLoaded;
BOOL mCacheDirty;
BOOL mAlive; // can become false if circuit disconnects
- BOOL mCapabilitiesReceived;
BOOL mSimulatorFeaturesReceived;
BOOL mReleaseNotesRequested;
BOOL mDead; //if true, this region is in the process of deleting.
BOOL mPaused; //pause processing the objects in the region
+ typedef enum
+ {
+ CAPABILITIES_STATE_INIT = 0,
+ CAPABILITIES_STATE_ERROR,
+ CAPABILITIES_STATE_RECEIVED
+ } eCababilitiesState;
+
+ eCababilitiesState mCapabilitiesState;
+
typedef std::map<U32, std::vector<U32> > orphan_list_t;
orphan_list_t mOrphanMap;
@@ -562,6 +578,10 @@ private:
LLFrameTimer mMaterialsCapThrottleTimer;
LLFrameTimer mRenderInfoRequestTimer;
LLFrameTimer mRenderInfoReportTimer;
+
+ // list of reflection maps being managed by this llviewer region
+ std::vector<LLPointer<LLReflectionMap> > mReflectionMaps;
+
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 086b433c72..e1bf1b6e6d 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -49,6 +49,8 @@
#include "lljoint.h"
#include "llskinningutil.h"
+//#pragma optimize("", off)
+
static LLStaticHashedString sTexture0("texture0");
static LLStaticHashedString sTexture1("texture1");
static LLStaticHashedString sTex0("tex0");
@@ -68,13 +70,6 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
-//transform shaders
-LLGLSLShader gTransformPositionProgram;
-LLGLSLShader gTransformTexCoordProgram;
-LLGLSLShader gTransformNormalProgram;
-LLGLSLShader gTransformColorProgram;
-LLGLSLShader gTransformTangentProgram;
-
//utility shaders
LLGLSLShader gOcclusionProgram;
LLGLSLShader gSkinnedOcclusionProgram;
@@ -82,6 +77,9 @@ LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
+LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gRadianceGenProgram;
+LLGLSLShader gIrradianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gTwoTextureCompareProgram;
@@ -254,10 +252,15 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gDeferredPBROpaqueProgram;
+LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
+LLGLSLShader gDeferredPBRAlphaProgram;
+LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
//helper for making a rigged variant of a given shader
bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
@@ -366,7 +369,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
mShaderList.push_back(&gDeferredWLMoonProgram);
- mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
+
}
LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -434,16 +440,9 @@ void LLViewerShaderMgr::setShaders()
}
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
-
- //NEVER use more than 16 texture channels (work around for prevalent driver bug)
- LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
-
- if (gGLManager.mGLSLVersionMajor < 1 ||
- (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20))
- { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier
- LLGLSLShader::sIndexedTextureChannels = 1;
- }
+
+ // when using indexed texture rendering, leave 8 texture units available for shadow and reflection maps
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-8, (S32) max_texture_index), 1);
reentrance = true;
@@ -457,7 +456,6 @@ void LLViewerShaderMgr::setShaders()
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater;
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::updateRenderDeferred();
@@ -486,11 +484,12 @@ void LLViewerShaderMgr::setShaders()
llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
- bool canRenderDeferred = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
- bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
+ //bool canRenderDeferred = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
+ //bool hasWindLightShaders = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
- bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred");
+ bool pbr = gSavedSettings.getBOOL("RenderPBR");
+ bool doingWindLight = true; //DEPRECATED -- hasWindLightShaders&& gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ bool useRenderDeferred = true; //DEPRECATED -- doingWindLight&& canRenderDeferred&& gSavedSettings.getBOOL("RenderDeferred");
S32 light_class = 3;
S32 interface_class = 2;
@@ -498,15 +497,8 @@ void LLViewerShaderMgr::setShaders()
S32 obj_class = 2;
S32 effect_class = 2;
S32 wl_class = 1;
- S32 water_class = 2;
+ S32 water_class = 3;
S32 deferred_class = 0;
- S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
-
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
- if (!use_transform_feedback)
- {
- transform_class = 0;
- }
if (useRenderDeferred)
{
@@ -528,6 +520,11 @@ void LLViewerShaderMgr::setShaders()
}
}
+ if (deferred_class > 0 && pbr)
+ {
+ deferred_class = 3;
+ }
+
if (doingWindLight)
{
// user has disabled WindLight in their settings, downgrade
@@ -554,17 +551,15 @@ void LLViewerShaderMgr::setShaders()
mShaderLevel[SHADER_EFFECT] = effect_class;
mShaderLevel[SHADER_WINDLIGHT] = wl_class;
mShaderLevel[SHADER_DEFERRED] = deferred_class;
- mShaderLevel[SHADER_TRANSFORM] = transform_class;
- BOOL loaded = loadBasicShaders();
- if (loaded)
+ std::string shader_name = loadBasicShaders();
+ if (shader_name.empty())
{
LL_INFOS() << "Loaded basic shaders." << LL_ENDL;
}
else
{
- LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL;
- llassert(loaded);
+ LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
reentrance = false; // For hygiene only, re-try probably helps nothing
return;
}
@@ -572,7 +567,7 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mShadersLoaded = true;
// Load all shaders to set max levels
- loaded = loadShadersEnvironment();
+ BOOL loaded = loadShadersEnvironment();
if (loaded)
{
@@ -641,89 +636,31 @@ void LLViewerShaderMgr::setShaders()
}
if (loaded)
-
- {
- loaded = loadTransformShaders();
- if (loaded)
- {
- LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
{
// Load max avatar shaders to set the max level
mShaderLevel[SHADER_AVATAR] = 3;
mMaxAvatarShaderLevel = 3;
-
- if (loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ if (loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
// cloth is a class3 shader
- S32 avatar_class = avatar_cloth ? 3 : 1;
+ S32 avatar_class = 1;
// Set the actual level
mShaderLevel[SHADER_AVATAR] = avatar_class;
loaded = loadShadersAvatar();
llassert(loaded);
-
- if (mShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)
- {
- avatar_cloth = true;
- }
- else
- {
- avatar_cloth = false;
- }
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
- }
}
else
{ //hardware skinning not possible, neither is deferred rendering
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_DEFERRED] = 0;
-
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
-
- loadShadersAvatar(); // unloads
-
- loaded = loadShadersObject();
- llassert(loaded);
+ llassert(false); // SHOULD NOT BE POSSIBLE
}
}
- if (!loaded)
- { //some shader absolutely could not load, try to fall back to a simpler setting
- if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
- { //disable windlight and try again
- gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
- LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
- }
-
llassert(loaded);
-
- if (loaded && !loadShadersDeferred())
- { //everything else succeeded but deferred failed, disable deferred and try again
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
+ loaded = loaded && loadShadersDeferred();
+ llassert(loaded);
if (gViewerWindow)
{
@@ -752,6 +689,9 @@ void LLViewerShaderMgr::unloadShaders()
gCustomAlphaProgram.unload();
gGlowCombineProgram.unload();
gSplatTextureRectProgram.unload();
+ gReflectionMipProgram.unload();
+ gRadianceGenProgram.unload();
+ gIrradianceGenProgram.unload();
gGlowCombineFXAAProgram.unload();
gTwoTextureAddProgram.unload();
gTwoTextureCompareProgram.unload();
@@ -840,12 +780,6 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredSkinnedDiffuseProgram.unload();
gDeferredSkinnedBumpProgram.unload();
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
-
mShaderLevel[SHADER_LIGHTING] = 0;
mShaderLevel[SHADER_OBJECT] = 0;
mShaderLevel[SHADER_AVATAR] = 0;
@@ -854,12 +788,11 @@ void LLViewerShaderMgr::unloadShaders()
mShaderLevel[SHADER_INTERFACE] = 0;
mShaderLevel[SHADER_EFFECT] = 0;
mShaderLevel[SHADER_WINDLIGHT] = 0;
- mShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mShadersLoaded = false;
}
-BOOL LLViewerShaderMgr::loadBasicShaders()
+std::string LLViewerShaderMgr::loadBasicShaders()
{
// Load basic dependency shaders first
// All of these have to load for any shaders to function
@@ -908,6 +841,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
@@ -942,11 +876,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_VERTEX_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
@@ -958,9 +892,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{ //use indexed texture rendering for GLSL >= 1.30
- ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
+ ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
}
+ bool has_reflection_probes = gSavedSettings.getS32("RenderReflectionProbeDetail") >= 0 && gGLManager.mGLVersion > 3.99f;
+
std::vector<S32> index_channels;
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
@@ -975,6 +911,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
@@ -1002,19 +939,20 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
- return TRUE;
+ return std::string();
}
BOOL LLViewerShaderMgr::loadShadersEnvironment()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
if (mShaderLevel[SHADER_ENVIRONMENT] == 0)
@@ -1036,8 +974,8 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
gTerrainProgram.mFeatures.disableTextureIndex = true;
gTerrainProgram.mFeatures.hasGamma = true;
gTerrainProgram.mShaderFiles.clear();
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER));
+ gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER));
gTerrainProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
success = gTerrainProgram.createShader(NULL, NULL);
llassert(success);
@@ -1050,12 +988,13 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
}
LLWorld::getInstance()->updateWaterObjects();
-
+#endif
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersWater()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
BOOL terrainWaterSuccess = TRUE;
@@ -1073,12 +1012,20 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterProgram.mName = "Water Shader";
gWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterProgram.mFeatures.hasAtmospherics = true;
+ gWaterProgram.mFeatures.hasWaterFog = true;
gWaterProgram.mFeatures.hasGamma = true;
gWaterProgram.mFeatures.hasTransport = true;
gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasReflectionProbes = true;
gWaterProgram.mShaderFiles.clear();
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterProgram.createShader(NULL, NULL);
@@ -1090,13 +1037,21 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterEdgeProgram.mName = "Water Edge Shader";
gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasWaterFog = true;
gWaterEdgeProgram.mFeatures.hasGamma = true;
gWaterEdgeProgram.mFeatures.hasTransport = true;
gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+ gWaterEdgeProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterEdgeProgram.createShader(NULL, NULL);
@@ -1110,10 +1065,15 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
gUnderWaterProgram.mFeatures.hasWaterFog = true;
gUnderWaterProgram.mShaderFiles.clear();
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gUnderWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
success = gUnderWaterProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1129,8 +1089,8 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gTerrainWaterProgram.mFeatures.disableTextureIndex = true;
gTerrainWaterProgram.mShaderFiles.clear();
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterV.glsl", GL_VERTEX_SHADER));
+ gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER));
gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -1168,6 +1128,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
LLWorld::getInstance()->updateWaterObjects();
+#endif
return TRUE;
}
@@ -1188,8 +1149,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
gGlowProgram.mName = "Glow Shader (Post)";
gGlowProgram.mShaderFiles.clear();
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowProgram.createShader(NULL, NULL);
if (!success)
@@ -1202,8 +1163,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
gGlowExtractProgram.mShaderFiles.clear();
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
@@ -1218,7 +1179,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
BOOL LLViewerShaderMgr::loadShadersDeferred()
{
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1;
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
@@ -1302,11 +1264,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredHighlightSpecularProgram.unload();
gNormalMapGenProgram.unload();
+ gDeferredGenBrdfLutProgram.unload();
+
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
gDeferredMaterialWaterProgram[i].unload();
}
+
+ gDeferredPBROpaqueProgram.unload();
+ gDeferredSkinnedPBROpaqueProgram.unload();
+ gDeferredPBRAlphaProgram.unload();
+ gDeferredSkinnedPBRAlphaProgram.unload();
+
return TRUE;
}
@@ -1316,8 +1286,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
gDeferredHighlightProgram.mShaderFiles.clear();
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightProgram.createShader(NULL, NULL);
}
@@ -1326,8 +1296,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightNormalProgram.mName = "Deferred Highlight Normals Shader";
gDeferredHighlightNormalProgram.mShaderFiles.clear();
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -1336,8 +1306,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightSpecularProgram.mName = "Deferred Highlight Spec Shader";
gDeferredHighlightSpecularProgram.mShaderFiles.clear();
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -1348,8 +1318,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
gDeferredDiffuseProgram.mShaderFiles.clear();
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
@@ -1361,8 +1331,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
@@ -1374,8 +1344,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
@@ -1386,8 +1356,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1399,8 +1369,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear();
gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL);
llassert(success);
@@ -1411,8 +1381,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mName = "Deferred Bump Shader";
gDeferredBumpProgram.mFeatures.encodesNormal = true;
gDeferredBumpProgram.mShaderFiles.clear();
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
success = success && gDeferredBumpProgram.createShader(NULL, NULL);
@@ -1448,8 +1418,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
U32 alpha_mode = i & 0x3;
gDeferredMaterialProgram[i].mShaderFiles.clear();
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialProgram[i].clearPermutations();
@@ -1484,6 +1454,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1497,7 +1473,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
-
+ gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true;
+
if (has_skin)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
@@ -1521,8 +1498,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
U32 alpha_mode = i & 0x3;
gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
- gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
@@ -1542,6 +1519,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1573,6 +1556,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
}
+ gDeferredMaterialWaterProgram[i].mFeatures.hasReflectionProbes = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
@@ -1611,14 +1595,105 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ if (success)
+ {
+ gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
+ gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
+ gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
+
+ gDeferredPBROpaqueProgram.mShaderFiles.clear();
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredPBROpaqueProgram.addPermutation("HAS_NORMAL_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("HAS_SPECULAR_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("HAS_EMISSIVE_MAP", "1");
+ gDeferredPBROpaqueProgram.addPermutation("DIFFUSE_ALPHA_MODE", "0");
+
+ success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
+ if (success)
+ {
+ success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
+ shader->mName = "Deferred PBR Alpha Shader";
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasTransport = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.isDeferred = true; // include deferredUtils
+ shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ shader->addPermutation("HAS_NORMAL_MAP", "1");
+ shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
+ shader->addPermutation("HAS_EMISSIVE_MAP", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ shader->addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ shader->addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ shader->addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram);
+ if (success)
+ {
+ success = shader->createShader(NULL, NULL);
+ }
+ llassert(success);
+
+ // Alpha Shader Hack
+ // See: LLRender::syncMatrices()
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+
+ shader->mRiggedVariant->mFeatures.calculatesLighting = true;
+ shader->mRiggedVariant->mFeatures.hasLighting = true;
+ }
+
if (success)
{
gDeferredTreeProgram.mName = "Deferred Tree Shader";
gDeferredTreeProgram.mShaderFiles.clear();
gDeferredTreeProgram.mFeatures.encodesNormal = true;
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTreeProgram.createShader(NULL, NULL);
}
@@ -1629,8 +1704,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTreeShadowProgram.mShaderFiles.clear();
gDeferredTreeShadowProgram.mFeatures.isDeferred = true;
gDeferredTreeShadowProgram.mFeatures.hasShadows = true;
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
@@ -1644,8 +1719,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true;
gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -1658,8 +1733,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredImpostorProgram.mFeatures.encodesNormal = true;
//gDeferredImpostorProgram.mFeatures.isDeferred = true;
gDeferredImpostorProgram.mShaderFiles.clear();
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredImpostorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1673,8 +1748,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredLightProgram.mFeatures.hasSrgb = true;
gDeferredLightProgram.mShaderFiles.clear();
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredLightProgram.clearPermutations();
@@ -1709,8 +1784,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiLightProgram[i].clearPermutations();
gDeferredMultiLightProgram[i].mShaderFiles.clear();
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
@@ -1743,8 +1818,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mFeatures.hasShadows = true;
gDeferredSpotLightProgram.clearPermutations();
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
if (ambient_kill)
@@ -1775,8 +1850,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiSpotLightProgram.clearPermutations();
gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
if (local_light_kill)
@@ -1815,8 +1890,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mName = "Deferred Sun Shader";
gDeferredSunProgram.mShaderFiles.clear();
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSunProgram.createShader(NULL, NULL);
@@ -1829,8 +1904,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.mFeatures.isDeferred = true;
gDeferredBlurLightProgram.mShaderFiles.clear();
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
@@ -1867,19 +1942,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.hasGamma = true;
shader->mFeatures.hasTransport = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.hasWaterFog = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_VERTEX_COLOR", "1");
@@ -1887,7 +1956,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->addPermutation("USE_INDEXED_TEX", "1");
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -1943,19 +2012,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.isAlphaLighting = true;
shader->mFeatures.encodesNormal = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_INDEXED_TEX", "1");
@@ -1970,7 +2032,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
@@ -2014,19 +2076,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->mFeatures.hasGamma = true;
shader[i]->mFeatures.hasTransport = true;
shader[i]->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader[i]->mFeatures.hasReflectionProbes = true;
+ shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
shader[i]->mShaderFiles.clear();
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader[i]->clearPermutations();
shader[i]->addPermutation("USE_INDEXED_TEX", "1");
@@ -2035,7 +2090,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->addPermutation("HAS_ALPHA_MASK", "1");
if (use_sun_shadow)
{
- shader[i]->addPermutation("HAS_SHADOW", "1");
+ shader[i]->addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -2085,8 +2140,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
gDeferredAvatarEyesProgram.mShaderFiles.clear();
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
llassert(success);
@@ -2101,8 +2156,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightProgram.mShaderFiles.clear();
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
@@ -2118,8 +2173,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
@@ -2137,8 +2192,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
@@ -2157,8 +2212,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
@@ -2176,11 +2231,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
llassert(success);
@@ -2194,8 +2250,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredEmissiveProgram.mFeatures.hasTransport = true;
gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredEmissiveProgram.mShaderFiles.clear();
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
@@ -2213,8 +2269,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWaterProgram.mFeatures.hasSrgb = true;
gDeferredWaterProgram.mShaderFiles.clear();
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER));
+ gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER));
gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredWaterProgram.createShader(NULL, NULL);
@@ -2234,8 +2290,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
//gDeferredUnderWaterProgram.mFeatures.hasShadows = true;
gDeferredUnderWaterProgram.mShaderFiles.clear();
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER));
gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
@@ -2253,13 +2309,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.mFeatures.hasGamma = true;
gDeferredSoftenProgram.mFeatures.isDeferred = true;
gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
gDeferredSoftenProgram.clearPermutations();
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (use_sun_shadow)
+ {
+ gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
if (ambient_kill)
{
gDeferredSoftenProgram.addPermutation("AMBIENT_KILL", "1");
@@ -2278,6 +2340,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
+ gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
}
success = gDeferredSoftenProgram.createShader(NULL, NULL);
@@ -2288,8 +2351,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
gDeferredSoftenWaterProgram.mShaderFiles.clear();
- gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenWaterProgram.clearPermutations();
gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2303,6 +2366,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+
+ if (use_sun_shadow)
+ {
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
if (ambient_kill)
{
@@ -2317,6 +2386,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (local_light_kill)
{
gDeferredSoftenWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");
}
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
@@ -2334,13 +2404,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowProgram.mFeatures.isDeferred = true;
gDeferredShadowProgram.mFeatures.hasShadows = true;
gDeferredShadowProgram.mShaderFiles.clear();
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
success = gDeferredShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2353,13 +2420,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2370,12 +2434,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
gDeferredShadowCubeProgram.mShaderFiles.clear();
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
llassert(success);
@@ -2387,14 +2448,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
@@ -2408,14 +2466,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
@@ -2428,12 +2483,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram;
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
@@ -2446,12 +2497,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
@@ -2463,12 +2510,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarShadowProgram.mShaderFiles.clear();
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2479,9 +2522,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2492,9 +2534,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2506,12 +2547,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2522,9 +2559,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2535,9 +2571,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader";
gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2559,8 +2594,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainProgram.mFeatures.hasTransport = true;
gDeferredTerrainProgram.mShaderFiles.clear();
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTerrainProgram.createShader(NULL, NULL);
llassert(success);
@@ -2582,8 +2617,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainWaterProgram.mFeatures.hasTransport = true;
gDeferredTerrainWaterProgram.mShaderFiles.clear();
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
@@ -2597,8 +2632,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.mFeatures.hasSkinning = true;
gDeferredAvatarProgram.mFeatures.encodesNormal = true;
gDeferredAvatarProgram.mShaderFiles.clear();
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarProgram.createShader(NULL, NULL);
llassert(success);
@@ -2620,17 +2655,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaProgram.clearPermutations();
gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
if (use_sun_shadow)
{
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
if (ambient_kill)
@@ -2662,20 +2698,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
llassert(success);
}
- if (success)
+ if (success && gGLManager.mGLVersion > 3.9f)
{
gFXAAProgram.mName = "FXAA Shader";
gFXAAProgram.mFeatures.isDeferred = true;
gFXAAProgram.mShaderFiles.clear();
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gFXAAProgram.createShader(NULL, NULL);
llassert(success);
@@ -2686,8 +2722,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostProgram.mName = "Deferred Post Shader";
gFXAAProgram.mFeatures.isDeferred = true;
gDeferredPostProgram.mShaderFiles.clear();
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostProgram.createShader(NULL, NULL);
llassert(success);
@@ -2698,8 +2734,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredCoFProgram.mName = "Deferred CoF Shader";
gDeferredCoFProgram.mShaderFiles.clear();
gDeferredCoFProgram.mFeatures.isDeferred = true;
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredCoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2710,8 +2746,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
gDeferredDoFCombineProgram.mShaderFiles.clear();
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
llassert(success);
@@ -2722,8 +2758,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";
gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
gDeferredPostNoDoFProgram.mShaderFiles.clear();
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2738,8 +2774,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSkyProgram.mFeatures.hasGamma = true;
gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
@@ -2756,8 +2792,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.mFeatures.hasGamma = true;
gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLCloudProgram.createShader(NULL, NULL);
@@ -2775,8 +2811,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSunProgram.mFeatures.disableTextureIndex = true;
gDeferredWLSunProgram.mFeatures.hasSrgb = true;
gDeferredWLSunProgram.mShaderFiles.clear();
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLSunProgram.createShader(NULL, NULL);
@@ -2795,8 +2831,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
gDeferredWLMoonProgram.mShaderFiles.clear();
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLMoonProgram.createShader(NULL, NULL);
@@ -2807,8 +2843,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredStarProgram.mName = "Deferred Star Program";
gDeferredStarProgram.mShaderFiles.clear();
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredStarProgram.createShader(NULL, NULL);
@@ -2819,13 +2855,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gNormalMapGenProgram.mName = "Normal Map Generation Program";
gNormalMapGenProgram.mShaderFiles.clear();
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB));
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gNormalMapGenProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
+ gDeferredGenBrdfLutProgram.mShaderFiles.clear();
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
+ }
+
+
return success;
}
@@ -2833,7 +2880,83 @@ BOOL LLViewerShaderMgr::loadShadersObject()
{
BOOL success = TRUE;
- if (success)
+ if (success)
+ {
+ gObjectBumpProgram.mName = "Bump Shader";
+ gObjectBumpProgram.mFeatures.encodesNormal = true;
+ gObjectBumpProgram.mShaderFiles.clear();
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
+ success = success && gObjectBumpProgram.createShader(NULL, NULL);
+ if (success)
+ { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
+ LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
+ for (int i = 0; i < 2; ++i)
+ {
+ shader[i]->bind();
+ shader[i]->uniform1i(sTexture0, 0);
+ shader[i]->uniform1i(sTexture1, 1);
+ shader[i]->unbind();
+ }
+ }
+ }
+
+ if (success)
+ {
+ gObjectSimpleProgram.mName = "Simple Shader";
+ gObjectSimpleProgram.mFeatures.calculatesLighting = true;
+ gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectSimpleProgram.mFeatures.hasGamma = true;
+ gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
+ gObjectSimpleProgram.mFeatures.hasLighting = true;
+ gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectSimpleProgram.mShaderFiles.clear();
+ gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
+ gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
+ success = success && gObjectSimpleProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectFullbrightProgram.mName = "Fullbright Shader";
+ gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectFullbrightProgram.mFeatures.hasGamma = true;
+ gObjectFullbrightProgram.mFeatures.hasTransport = true;
+ gObjectFullbrightProgram.mFeatures.isFullbright = true;
+ gObjectFullbrightProgram.mFeatures.hasSrgb = true;
+ gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectFullbrightProgram.mShaderFiles.clear();
+ gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
+ success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader";
+ gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
+ gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER));
+ gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
+ success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
{
gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";
gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;
@@ -2843,8 +2966,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true;
gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true;
gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
}
@@ -2859,13 +2982,15 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true;
gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true;
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);
}
+#if 1 // DEPRECATED -- forward rendering is deprecated
+
if (success)
{
gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader";
@@ -2877,8 +3002,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2894,8 +3019,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
@@ -2912,8 +3037,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
}
@@ -2929,8 +3054,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
@@ -2947,8 +3072,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gTreeProgram.mFeatures.disableTextureIndex = true;
gTreeProgram.mFeatures.hasAlphaMask = true;
gTreeProgram.mShaderFiles.clear();
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER));
+ gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gTreeProgram.createShader(NULL, NULL);
}
@@ -2964,8 +3089,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gTreeWaterProgram.mFeatures.disableTextureIndex = true;
gTreeWaterProgram.mFeatures.hasAlphaMask = true;
gTreeWaterProgram.mShaderFiles.clear();
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER));
+ gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gTreeWaterProgram.createShader(NULL, NULL);
@@ -2981,8 +3106,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true;
gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true;
gObjectFullbrightNoColorProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);
}
@@ -2996,8 +3121,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true;
gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);
@@ -3009,8 +3134,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gImpostorProgram.mFeatures.disableTextureIndex = true;
gImpostorProgram.mFeatures.hasSrgb = true;
gImpostorProgram.mShaderFiles.clear();
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gImpostorProgram.createShader(NULL, NULL);
}
@@ -3026,8 +3151,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
gObjectPreviewProgram.mShaderFiles.clear();
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectPreviewProgram.createShader(NULL, NULL);
gObjectPreviewProgram.mFeatures.hasLighting = true;
@@ -3044,8 +3169,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
gPhysicsPreviewProgram.mShaderFiles.clear();
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER_ARB));
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gPhysicsPreviewProgram.createShader(NULL, NULL);
gPhysicsPreviewProgram.mFeatures.hasLighting = false;
@@ -3053,23 +3178,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectSimpleProgram.mName = "Simple Shader";
- gObjectSimpleProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasGamma = true;
- gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasLighting = true;
- gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleProgram.mShaderFiles.clear();
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
- success = success && gObjectSimpleProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
@@ -3082,8 +3190,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
//
gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleImpostorProgram.mShaderFiles.clear();
- gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram);
success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL);
@@ -3099,8 +3207,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleWaterProgram.mShaderFiles.clear();
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram);
@@ -3109,30 +3217,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectBumpProgram.mName = "Bump Shader";
- gObjectBumpProgram.mFeatures.encodesNormal = true;
- gObjectBumpProgram.mShaderFiles.clear();
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
- success = success && gObjectBumpProgram.createShader(NULL, NULL);
- if (success)
- { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
- LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
- for (int i = 0; i < 2; ++i)
- {
- shader[i]->bind();
- shader[i]->uniform1i(sTexture0, 0);
- shader[i]->uniform1i(sTexture1, 1);
- shader[i]->unbind();
- }
- }
- }
-
-
- if (success)
- {
gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
@@ -3142,8 +3226,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram);
success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
@@ -3160,8 +3244,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER));
+ gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram);
@@ -3170,23 +3254,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectFullbrightProgram.mName = "Fullbright Shader";
- gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightProgram.mFeatures.hasGamma = true;
- gObjectFullbrightProgram.mFeatures.hasTransport = true;
- gObjectFullbrightProgram.mFeatures.isFullbright = true;
- gObjectFullbrightProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightProgram.mShaderFiles.clear();
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
- success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
@@ -3194,8 +3261,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightWaterProgram.mShaderFiles.clear();
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram);
@@ -3212,8 +3279,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveProgram.mFeatures.hasSrgb = true;
gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectEmissiveProgram.mShaderFiles.clear();
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER));
+ gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram);
success = success && gObjectEmissiveProgram.createShader(NULL, NULL);
@@ -3228,8 +3295,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectEmissiveWaterProgram.mShaderFiles.clear();
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER));
+ gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram);
@@ -3247,8 +3314,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram);
success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
@@ -3264,8 +3331,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram);
@@ -3282,8 +3349,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyProgram.mFeatures.isShiny = true;
gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectShinyProgram.mShaderFiles.clear();
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER));
+ gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER));
gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram);
success = success && gObjectShinyProgram.createShader(NULL, NULL);
@@ -3299,8 +3366,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true;
gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectShinyWaterProgram.mShaderFiles.clear();
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
+ gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER));
+ gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER));
gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram);
@@ -3317,43 +3384,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightShinyProgram.mShaderFiles.clear();
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram);
success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
- if (success)
- {
- gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader";
- gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
- success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
- }
+#endif
+
+ if (!success)
+ {
+ mShaderLevel[SHADER_OBJECT] = 0;
+ return FALSE;
+ }
- if( !success )
- {
- mShaderLevel[SHADER_OBJECT] = 0;
- return FALSE;
- }
-
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersAvatar()
{
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
if (mShaderLevel[SHADER_AVATAR] == 0)
@@ -3377,8 +3428,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarProgram.mFeatures.hasAlphaMask = true;
gAvatarProgram.mFeatures.disableTextureIndex = true;
gAvatarProgram.mShaderFiles.clear();
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarProgram.createShader(NULL, NULL);
@@ -3394,8 +3445,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarWaterProgram.mFeatures.hasAlphaMask = true;
gAvatarWaterProgram.mFeatures.disableTextureIndex = true;
gAvatarWaterProgram.mShaderFiles.clear();
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
// Note: no cloth under water:
gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1);
gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -3415,8 +3466,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarPickProgram.mFeatures.hasSkinning = true;
gAvatarPickProgram.mFeatures.disableTextureIndex = true;
gAvatarPickProgram.mShaderFiles.clear();
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER));
gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarPickProgram.createShader(NULL, NULL);
}
@@ -3433,8 +3484,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
gAvatarEyeballProgram.mShaderFiles.clear();
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarEyeballProgram.createShader(NULL, NULL);
}
@@ -3445,7 +3496,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
mMaxAvatarShaderLevel = 0;
return FALSE;
}
-
+#endif
return TRUE;
}
@@ -3457,8 +3508,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightProgram.mName = "Highlight Shader";
gHighlightProgram.mShaderFiles.clear();
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
success = success && gHighlightProgram.createShader(NULL, NULL);
@@ -3468,8 +3519,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightNormalProgram.mName = "Highlight Normals Shader";
gHighlightNormalProgram.mShaderFiles.clear();
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -3478,8 +3529,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightSpecularProgram.mName = "Highlight Spec Shader";
gHighlightSpecularProgram.mShaderFiles.clear();
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -3488,8 +3539,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gUIProgram.mName = "UI Shader";
gUIProgram.mShaderFiles.clear();
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gUIProgram.createShader(NULL, NULL);
}
@@ -3498,8 +3549,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingProgram.mName = "Pathfinding Shader";
gPathfindingProgram.mShaderFiles.clear();
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingProgram.createShader(NULL, NULL);
}
@@ -3508,8 +3559,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
gPathfindingNoNormalsProgram.mShaderFiles.clear();
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
}
@@ -3518,8 +3569,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gCustomAlphaProgram.mName = "Custom Alpha Shader";
gCustomAlphaProgram.mShaderFiles.clear();
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB));
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER));
+ gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER));
gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCustomAlphaProgram.createShader(NULL, NULL);
}
@@ -3528,8 +3579,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gSplatTextureRectProgram.mName = "Splat Texture Rect Shader";
gSplatTextureRectProgram.mShaderFiles.clear();
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB));
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER));
gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSplatTextureRectProgram.createShader(NULL, NULL);
if (success)
@@ -3544,8 +3595,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gGlowCombineProgram.mName = "Glow Combine Shader";
gGlowCombineProgram.mShaderFiles.clear();
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineProgram.createShader(NULL, NULL);
if (success)
@@ -3561,8 +3612,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
gGlowCombineFXAAProgram.mShaderFiles.clear();
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
if (success)
@@ -3574,13 +3625,12 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
}
}
-
if (success)
{
gTwoTextureAddProgram.mName = "Two Texture Add Shader";
gTwoTextureAddProgram.mShaderFiles.clear();
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER));
gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureAddProgram.createShader(NULL, NULL);
if (success)
@@ -3596,8 +3646,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
gTwoTextureCompareProgram.mShaderFiles.clear();
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureCompareProgram.createShader(NULL, NULL);
if (success)
@@ -3613,8 +3663,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOneTextureFilterProgram.mName = "One Texture Filter Shader";
gOneTextureFilterProgram.mShaderFiles.clear();
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureFilterProgram.createShader(NULL, NULL);
if (success)
@@ -3629,8 +3679,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
gOneTextureNoColorProgram.mShaderFiles.clear();
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER));
+ gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER));
gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureNoColorProgram.createShader(NULL, NULL);
if (success)
@@ -3644,8 +3694,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gSolidColorProgram.mName = "Solid Color Shader";
gSolidColorProgram.mShaderFiles.clear();
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB));
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSolidColorProgram.createShader(NULL, NULL);
if (success)
@@ -3660,8 +3710,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionProgram.mName = "Occlusion Shader";
gOcclusionProgram.mShaderFiles.clear();
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
success = gOcclusionProgram.createShader(NULL, NULL);
@@ -3672,8 +3722,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
gSkinnedOcclusionProgram.mShaderFiles.clear();
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
}
@@ -3682,8 +3732,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
gOcclusionCubeProgram.mShaderFiles.clear();
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOcclusionCubeProgram.createShader(NULL, NULL);
}
@@ -3692,8 +3742,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDebugProgram.mName = "Debug Shader";
gDebugProgram.mShaderFiles.clear();
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
@@ -3704,8 +3754,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gClipProgram.mName = "Clip Shader";
gClipProgram.mShaderFiles.clear();
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gClipProgram.createShader(NULL, NULL);
}
@@ -3714,8 +3764,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDownsampleDepthProgram.mName = "DownsampleDepth Shader";
gDownsampleDepthProgram.mShaderFiles.clear();
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER));
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER));
gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthProgram.createShader(NULL, NULL);
}
@@ -3724,8 +3774,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gBenchmarkProgram.createShader(NULL, NULL);
}
@@ -3734,8 +3784,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
gDownsampleDepthRectProgram.mShaderFiles.clear();
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER));
gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
}
@@ -3744,12 +3794,49 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gAlphaMaskProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gReflectionMipProgram.mName = "Reflection Mip Shader";
+ gReflectionMipProgram.mFeatures.isDeferred = true;
+ gReflectionMipProgram.mShaderFiles.clear();
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionMipProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gReflectionMipProgram.bind();
+ gReflectionMipProgram.uniform1i(sScreenMap, 0);
+ gReflectionMipProgram.unbind();
+ }
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gRadianceGenProgram.mName = "Radiance Gen Shader";
+ gRadianceGenProgram.mShaderFiles.clear();
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gRadianceGenProgram.createShader(NULL, NULL);
+ }
+
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gIrradianceGenProgram.mName = "Irradiance Gen Shader";
+ gIrradianceGenProgram.mShaderFiles.clear();
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER));
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gIrradianceGenProgram.createShader(NULL, NULL);
+ }
+
if( !success )
{
mShaderLevel[SHADER_INTERFACE] = 0;
@@ -3762,7 +3849,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
BOOL LLViewerShaderMgr::loadShadersWindLight()
{
BOOL success = TRUE;
-
+#if 1 // DEPRECATED -- forward rendering is deprecated
if (mShaderLevel[SHADER_WINDLIGHT] < 2)
{
gWLSkyProgram.unload();
@@ -3780,8 +3867,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLSkyProgram.mFeatures.hasTransport = true;
gWLSkyProgram.mFeatures.hasGamma = true;
gWLSkyProgram.mFeatures.hasSrgb = true;
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER));
+ gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER));
gWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLSkyProgram.createShader(NULL, NULL);
@@ -3795,8 +3882,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.mFeatures.hasTransport = true;
gWLCloudProgram.mFeatures.hasGamma = true;
gWLCloudProgram.mFeatures.hasSrgb = true;
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER));
+ gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER));
gWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLCloudProgram.createShader(NULL, NULL);
@@ -3813,8 +3900,8 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLSunProgram.mFeatures.isFullbright = true;
gWLSunProgram.mFeatures.disableTextureIndex = true;
gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER));
gWLSunProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLSunProgram.createShader(NULL, NULL);
@@ -3831,102 +3918,13 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLMoonProgram.mFeatures.isFullbright = true;
gWLMoonProgram.mFeatures.disableTextureIndex = true;
gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER));
+ gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER));
gWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gWLMoonProgram.createShader(NULL, NULL);
}
-
- return success;
-}
-
-BOOL LLViewerShaderMgr::loadTransformShaders()
-{
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_TRANSFORM] < 1)
- {
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gTransformPositionProgram.mName = "Position Transform Shader";
- gTransformPositionProgram.mShaderFiles.clear();
- gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "position_out",
- "texture_index_out",
- };
-
- success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
- }
-
- if (success)
- {
- gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
- gTransformTexCoordProgram.mShaderFiles.clear();
- gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "texcoord_out",
- };
-
- success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformNormalProgram.mName = "Normal Transform Shader";
- gTransformNormalProgram.mShaderFiles.clear();
- gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "normal_out",
- };
-
- success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformColorProgram.mName = "Color Transform Shader";
- gTransformColorProgram.mShaderFiles.clear();
- gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "color_out",
- };
-
- success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformTangentProgram.mName = "Binormal Transform Shader";
- gTransformTangentProgram.mShaderFiles.clear();
- gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "tangent_out",
- };
-
- success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
- }
-
-
+#endif
return success;
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 93bb29a355..a2ae984caa 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -49,7 +49,11 @@ public:
void setShaders();
void unloadShaders();
S32 getShaderLevel(S32 type);
- BOOL loadBasicShaders();
+
+ // loadBasicShaders in case of a failure returns
+ // name of a file error happened at, otherwise
+ // returns an empty string
+ std::string loadBasicShaders();
BOOL loadShadersEffects();
BOOL loadShadersDeferred();
BOOL loadShadersObject();
@@ -58,7 +62,6 @@ public:
BOOL loadShadersWater();
BOOL loadShadersInterface();
BOOL loadShadersWindLight();
- BOOL loadTransformShaders();
std::vector<S32> mShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -74,7 +77,6 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
- SHADER_TRANSFORM,
SHADER_COUNT
};
@@ -146,21 +148,15 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
extern LLVector4 gShinyOrigin;
-//transform shaders
-extern LLGLSLShader gTransformPositionProgram;
-extern LLGLSLShader gTransformTexCoordProgram;
-extern LLGLSLShader gTransformNormalProgram;
-extern LLGLSLShader gTransformColorProgram;
-extern LLGLSLShader gTransformTangentProgram;
-
-
-
//utility shaders
extern LLGLSLShader gOcclusionProgram;
extern LLGLSLShader gOcclusionCubeProgram;
extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gSplatTextureRectProgram;
+extern LLGLSLShader gReflectionMipProgram;
+extern LLGLSLShader gRadianceGenProgram;
+extern LLGLSLShader gIrradianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
@@ -309,8 +305,12 @@ extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gNormalMapGenProgram;
+extern LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+
+extern LLGLSLShader gDeferredPBROpaqueProgram;
+extern LLGLSLShader gDeferredPBRAlphaProgram;
#endif
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 57d52ae9ee..5d936dfc90 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -488,7 +488,9 @@ void send_viewer_stats(bool include_preferences)
system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
system["os"] = LLOSInfo::instance().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
+ system["cpu_sse"] = gSysCPU.getSSEVersions();
system["address_size"] = ADDRESS_SIZE;
+ system["os_bitness"] = LLOSInfo::instance().getOSBitness();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
LLUUID::getNodeID(MACAddress);
std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index e2de7ac825..3f302d4f45 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -42,6 +42,7 @@
#include "lllandmark.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
+#include "llmaterialeditor.h"
#include "llmemorystream.h"
#include "llmenugl.h"
#include "llnotecard.h"
@@ -542,6 +543,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break;
case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break;
case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break;
+ case LLAssetType::AT_MATERIAL: img_name = "Inv_Material"; break;
default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
}
@@ -879,6 +881,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
+ case DAD_MATERIAL:
{
supported = true;
break;
@@ -1126,6 +1129,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwch
case LLAssetType::AT_SETTINGS:
openEmbeddedSetting(item, wc);
return TRUE;
+ case LLAssetType::AT_MATERIAL:
+ openEmbeddedGLTFMaterial(item, wc);
+ return TRUE;
case LLAssetType::AT_NOTECARD:
case LLAssetType::AT_LSL_TEXT:
case LLAssetType::AT_CLOTHING:
@@ -1212,6 +1218,26 @@ void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc)
}
}
+void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc)
+{
+ if (!item)
+ {
+ return;
+ }
+
+ LLSD floater_key;
+ floater_key["objectid"] = mObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ LLMaterialEditor* preview = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (preview)
+ {
+ preview->setAuxItem(item);
+ preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
+ preview->openFloater(floater_key);
+ preview->setFocus(TRUE);
+ }
+}
+
void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
{
LLSD payload;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index a6d7fef409..6170d476b8 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -108,6 +108,7 @@ private:
void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void openEmbeddedSetting(LLInventoryItem* item, llwchar wc);
+ void openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
void showUnsavedAlertDialog( LLInventoryItem* item );
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 3584fffd44..590f24d359 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -76,9 +76,10 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultIrradiancePBRp;
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL;
-F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f;
+F32 LLViewerFetchedTexture::sMaxVirtualSize = 8192.f*8192.f;
const std::string sTesterName("TextureTester");
@@ -99,7 +100,6 @@ U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
bool LLViewerTexture::sFreezeImageUpdates = false;
F32 LLViewerTexture::sCurrentTime = 0.0f;
-F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
@@ -286,6 +286,13 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
return tex;
}
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
+{
+ LLViewerFetchedTexture* ret = new LLViewerFetchedTexture(raw, type, usemipmaps);
+ gTextureList.addImage(ret, TEX_LIST_STANDARD);
+ return ret;
+}
+
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
const LLUUID &image_id,
FTType f_type,
@@ -451,6 +458,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sWhiteImagep = NULL;
LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
LLViewerMediaTexture::cleanUpClass();
}
@@ -802,7 +810,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
mNeedsGLTexture = TRUE;
}
- virtual_size *= sTexelPixelRatio;
+ virtual_size = llmin(virtual_size, LLViewerFetchedTexture::sMaxVirtualSize);
if (virtual_size > mMaxVirtualSize)
{
@@ -1905,8 +1913,7 @@ bool LLViewerFetchedTexture::updateFetch()
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
- if(textures_decode_disabled ||
- (gUseWireframe && mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED_SELF)) // don't fetch the surface textures in wireframe mode
+ if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
{
return false;
}
@@ -2052,7 +2059,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (!mIsFetching)
{
- if ((decode_priority > 0) && (mRawDiscardLevel < 0))
+ if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
{
// We finished but received no data
if (getDiscardLevel() < 0)
@@ -2107,7 +2114,7 @@ bool LLViewerFetchedTexture::updateFetch()
desired_discard = llmin(desired_discard, getMaxDiscardLevel());
bool make_request = true;
- /*if (decode_priority <= 0)
+ if (decode_priority <= 0)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
make_request = false;
@@ -2117,7 +2124,7 @@ bool LLViewerFetchedTexture::updateFetch()
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
make_request = false;
}
- else */ if (mNeedsCreateTexture || mIsMissingAsset)
+ else if (mNeedsCreateTexture || mIsMissingAsset)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
make_request = false;
@@ -2198,16 +2205,18 @@ bool LLViewerFetchedTexture::updateFetch()
}
// bypass texturefetch directly by pulling from LLTextureCache
- bool fetch_request_created = false;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
+ S32 fetch_request_discard = -1;
+ fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
w, h, c, desired_discard, needsAux(), mCanUseHTTP);
- if (fetch_request_created)
+ if (fetch_request_discard >= 0)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
mHasFetcher = TRUE;
mIsFetching = TRUE;
- mRequestedDiscardLevel = desired_discard;
+ // in some cases createRequest can modify discard, as an example
+ // bake textures are always at discard 0
+ mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard);
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 8c41c4a6bc..312e2ca365 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -218,7 +218,6 @@ protected:
LL::WorkQueue::weak_t mMainQueue;
LL::WorkQueue::weak_t mImageQueue;
- static F32 sTexelPixelRatio;
public:
static const U32 sCurrentFileVersion;
static S32 sImageCount;
@@ -531,6 +530,7 @@ public:
static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
+ static LLPointer<LLViewerFetchedTexture> sDefaultIrradiancePBRp; // PBR: irradiance
};
//
@@ -660,6 +660,8 @@ public:
static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps);
+
static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
FTType f_type = FTT_DEFAULT,
BOOL usemipmap = TRUE,
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 8faeb70553..55a735e906 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -50,6 +50,7 @@
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llviewermedia.h"
+#include "llviewernetwork.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "pipeline.h"
@@ -120,7 +121,10 @@ void LLViewerTextureList::doPreloadImages()
// Set the default flat normal map
LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP);
-
+
+ // PBR: irradiance
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = LLViewerTextureManager::getFetchedTextureFromFile("default_irradiance.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+
image_list->initFromFile();
// turn off clamping and bilinear filtering for uv picking images
@@ -152,12 +156,6 @@ void LLViewerTextureList::doPreloadImages()
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
- if (image)
- {
- image->setAddressMode(LLTexUnit::TAM_WRAP);
- mImagePreloads.insert(image);
- }
image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
0, 0, IMG_TRANSPARENT);
if (image)
@@ -190,13 +188,31 @@ void LLViewerTextureList::doPreloadImages()
static std::string get_texture_list_name()
{
- return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+ if (LLGridManager::getInstance()->isInProductionGrid())
+ {
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+ "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+ }
+ else
+ {
+ const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
+ const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+ "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml");
+ }
}
void LLViewerTextureList::doPrefetchImages()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ if (imagep)
+ {
+ imagep->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(imagep);
+ }
+
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@@ -1166,14 +1182,15 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
- const U8 codec)
+ const U8 codec,
+ const S32 max_image_dimentions)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
- image->setLastError("Couldn't open the image to be uploaded.");
+ LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL;
return FALSE;
}
if (!image->load(filename))
@@ -1195,7 +1212,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
return FALSE;
}
// Convert to j2c (JPEG2000) and save the file locally
- LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
@@ -1220,15 +1237,18 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_lossless)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
- if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
- (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
- compressedImage->setReversible(TRUE);
+ if (force_lossless ||
+ (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
+ (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)))
+ {
+ compressedImage->setReversible(TRUE);
+ }
if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
@@ -1255,152 +1275,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
///////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
-{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-
- // Receive image header, copy into image object and decompresses
- // if this is a one-packet image.
-
- LLUUID id;
-
- char ip_string[256];
- u32_to_ip_string(msg->getSenderIP(),ip_string);
-
- U32Bytes received_size ;
- if (msg->getReceiveCompressedSize())
- {
- received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
- }
- else
- {
- received_size = (U32Bytes)msg->getReceiveSize() ;
- }
- add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size);
- add(LLStatViewer::TEXTURE_PACKETS, 1);
-
- U8 codec;
- U16 packets;
- U32 totalbytes;
- msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
- msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec);
- msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets);
- msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes);
-
- S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
- if (!data_size)
- {
- return;
- }
- if (data_size < 0)
- {
- // msg->getSizeFast() is probably trying to tell us there
- // was an error.
- LL_ERRS() << "image header chunk size was negative: "
- << data_size << LL_ENDL;
- return;
- }
-
- // this buffer gets saved off in the packet list
- U8 *data = new U8[data_size];
- msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (!image)
- {
- delete [] data;
- return;
- }
- if(log_texture_traffic)
- {
- gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
- }
-
- //image->getLastPacketTimer()->reset();
- bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data);
- if (!res)
- {
- delete[] data;
- }
-}
-
-// static
-void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
-{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-
- // Receives image packet, copy into image object,
- // checks if all packets received, decompresses if so.
-
- LLUUID id;
- U16 packet_num;
-
- char ip_string[256];
- u32_to_ip_string(msg->getSenderIP(),ip_string);
-
- U32Bytes received_size ;
- if (msg->getReceiveCompressedSize())
- {
- received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
- }
- else
- {
- received_size = (U32Bytes)msg->getReceiveSize() ;
- }
-
- add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size));
- add(LLStatViewer::TEXTURE_PACKETS, 1);
-
- //llprintline("Start decode, image header...");
- msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
- msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
- S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
-
- if (!data_size)
- {
- return;
- }
- if (data_size < 0)
- {
- // msg->getSizeFast() is probably trying to tell us there
- // was an error.
- LL_ERRS() << "image data chunk size was negative: "
- << data_size << LL_ENDL;
- return;
- }
- if (data_size > MTUBYTES)
- {
- LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL;
- return;
- }
- U8 *data = new U8[data_size];
- msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- if (!image)
- {
- delete [] data;
- return;
- }
- if(log_texture_traffic)
- {
- gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
- }
-
- //image->getLastPacketTimer()->reset();
- bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
- if (!res)
- {
- delete[] data;
- }
-}
-
-
// We've been that the asset server does not contain the requested image id.
// static
void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index bd60c990b5..454574f7d6 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -1,10 +1,10 @@
/**
- * @file llviewertexturelinumimagest.h
+ * @file llviewertexturelist.h
* @brief Object for managing the list of images within a region
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -92,11 +92,12 @@ class LLViewerTextureList
friend class LLLocalBitmap;
public:
- static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
- static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
+ static BOOL createUploadFile(const std::string& filename,
+ const std::string& out_filename,
+ const U8 codec,
+ const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, bool force_lossless = false);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
- static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
- static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
public:
LLViewerTextureList();
@@ -126,7 +127,9 @@ public:
S32 getNumImages() { return mImageList.size(); }
+ // Local UI images
void doPreloadImages();
+ // Network images. Needs caps and cache to work
void doPrefetchImages();
void clearFetchingRequests();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 15f20d1d34..88058d1137 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -103,7 +103,6 @@
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloater.h"
-#include "llfloaterbuildoptions.h"
#include "llfloaterbuyland.h"
#include "llfloatercamera.h"
#include "llfloaterland.h"
@@ -228,6 +227,7 @@ extern BOOL gDebugClicks;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDepthDirty;
extern BOOL gResizeScreenTexture;
+extern BOOL gCubeSnapshot;
LLViewerWindow *gViewerWindow = NULL;
@@ -597,29 +597,6 @@ public:
{
LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
- if (gGLManager.mHasATIMemInfo)
- {
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
-
- addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
-
- if (gGLManager.mHasVertexBufferObject)
- {
- glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
- addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
- }
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
- ypos += y_inc;
- }
-
//show streaming cost/triangle count of known prims in current region OR selection
{
F32 cost = 0.f;
@@ -761,6 +738,12 @@ public:
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
ypos += y_inc;
}
@@ -1556,9 +1539,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
showCursor();
getWindow()->setMouseClipping(FALSE);
- // If losing focus while keys are down, reset them.
+ // If losing focus while keys are down, handle them as
+ // an 'up' to correctly release states, then reset states
if (gKeyboard)
{
+ gKeyboard->resetKeyDownAndHandle();
gKeyboard->resetKeys();
}
@@ -1900,7 +1885,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.getBOOL("RenderVSyncEnable"),
!gHeadlessClient,
p.ignore_pixel_depth,
- gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
+ 0); //don't use window level anti-aliasing
if (NULL == mWindow)
{
@@ -1979,14 +1964,9 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
// Initialize OpenGL Renderer
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
- {
- gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
- }
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- gGL.init() ;
+ gGL.init(true);
if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -1997,11 +1977,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
}
- if (!gGLManager.mHasDepthClamp)
- {
- LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
- }
-
// If we crashed while initializng GL stuff last time, disable certain features
if (gSavedSettings.getBOOL("RenderInitError"))
{
@@ -2221,6 +2196,7 @@ void LLViewerWindow::initWorldUI()
gStatusBar->setShape(status_bar_container->getLocalRect());
// sync bg color with menu bar
gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
+ // add InBack so that gStatusBar won't be drawn over menu
status_bar_container->addChildInBack(gStatusBar);
status_bar_container->setVisible(TRUE);
@@ -2498,10 +2474,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
//glViewport(0, 0, width, height );
- if (height > 0)
+ LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist
+ if (height > 0 && camera)
{
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ camera->setAspect( getWorldViewAspectRatio() );
}
calcDisplayScale();
@@ -3200,6 +3177,11 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
void LLViewerWindow::handleScrollHWheel(S32 clicks)
{
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+
LLUI::getInstance()->resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
@@ -3358,7 +3340,7 @@ void LLViewerWindow::updateUI()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
{
gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE,
&gDebugRaycastFaceHit,
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
@@ -4182,13 +4164,16 @@ void LLViewerWindow::pickAsync( S32 x,
BOOL pick_rigged,
BOOL pick_unselectable)
{
- BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
- {
- // build mode allows interaction with all transparent objects
- // "Show Debug Alpha" means no object actually transparent
- pick_transparent = TRUE;
- }
+ // "Show Debug Alpha" means no object actually transparent
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
+ if (LLDrawPoolAlpha::sShowDebugAlpha)
+ {
+ pick_transparent = TRUE;
+ }
+ else if (in_build_mode && !gSavedSettings.getBOOL("SelectInvisibleObjects"))
+ {
+ pick_transparent = FALSE;
+ }
LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
schedulePick(pick_info);
@@ -4246,10 +4231,10 @@ void LLViewerWindow::returnEmptyPicks()
}
// Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@@ -4295,6 +4280,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
S32 this_face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a *intersection,
LLVector2 *uv,
@@ -4365,7 +4351,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged,
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4373,7 +4359,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged,
+ if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4387,7 +4373,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged,
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
@@ -4645,8 +4631,8 @@ void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
else
pick_type = LLFilePicker::FFSAVE_ALL;
- (new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
- boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
+ boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb));
}
else
{
@@ -4860,7 +4846,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// PRE SNAPSHOT
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
// Hide all the UI widgets first and draw a frame
@@ -4914,8 +4900,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))
{
- original_width = gPipeline.mDeferredScreen.getWidth();
- original_height = gPipeline.mDeferredScreen.getHeight();
+ original_width = gPipeline.mRT->deferredScreen.getWidth();
+ original_height = gPipeline.mRT->deferredScreen.getHeight();
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
@@ -4994,8 +4980,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
- gObjectList.generatePickList(*LLViewerCamera::getInstance());
-
// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
@@ -5158,9 +5142,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
@@ -5172,13 +5157,13 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
LLPipeline::sShowHUDAttachments = FALSE;
LLRect window_rect = getWorldViewRectRaw();
- S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
- S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
+ S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
+ S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
LLRenderTarget scratch_space;
U32 color_fmt = GL_RGBA;
const bool use_depth_buffer = true;
- const bool use_stencil_buffer = true;
+ const bool use_stencil_buffer = false;
if (scratch_space.allocate(image_width, image_height, color_fmt, use_depth_buffer, use_stencil_buffer))
{
if (gPipeline.allocateScreenBuffer(image_width, image_height))
@@ -5254,6 +5239,149 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
return true;
}
+void display_cube_face();
+
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render)
+{
+ // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
+ LL_PROFILE_GPU_ZONE("cubeSnapshot");
+ llassert(LLPipeline::sRenderDeferred);
+ llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress
+
+ U32 res = gPipeline.mRT->deferredScreen.getWidth();
+
+ //llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
+ //llassert(res <= gPipeline.mRT->deferredScreen.getHeight());
+
+ // save current view/camera settings so we can restore them afterwards
+ S32 old_occlusion = LLPipeline::sUseOcclusion;
+
+ // set new parameters specific to the 360 requirements
+ LLPipeline::sUseOcclusion = 0;
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ LLViewerCamera saved_camera = LLViewerCamera::instance();
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_mod = get_current_modelview();
+
+ // camera constants for the square, cube map capture image
+ camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
+ camera->setView(F_PI_BY_TWO);
+ camera->yaw(0.0);
+ camera->setOrigin(origin);
+ camera->setNear(near_clip);
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
+
+ U32 dynamic_render_types[] = {
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_PARTICLES
+ };
+ constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32);
+ bool prev_dynamic_render_type[dynamic_render_type_count];
+
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ prev_dynamic_render_type[i] = gPipeline.hasRenderType(dynamic_render_types[i]);
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ LLPipeline::sShowHUDAttachments = FALSE;
+ LLRect window_rect = getWorldViewRectRaw();
+
+ mWorldViewRectRaw.set(0, res, res, 0);
+
+ // these are the 6 directions we will point the camera, see LLCubeMapArray::sTargets
+ LLVector3 look_dirs[6] = {
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+ };
+
+ LLVector3 look_upvecs[6] = {
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+ };
+
+ // for each of six sides of cubemap
+ //for (int i = 0; i < 6; ++i)
+ int i = face;
+ {
+ // set up camera to look in each direction
+ camera->lookDir(look_dirs[i], look_upvecs[i]);
+
+ // turning this flag off here prohibits the screen swap
+ // to present the new page to the viewer - this stops
+ // the black flash in between captures when the number
+ // of render passes is more than 1. We need to also
+ // set it here because code in LLViewerDisplay resets
+ // it to TRUE each time.
+ gDisplaySwapBuffers = FALSE;
+
+ // actually render the scene
+ gCubeSnapshot = TRUE;
+ display_cube_face();
+ gCubeSnapshot = FALSE;
+ }
+
+ gDisplaySwapBuffers = TRUE;
+
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+ }
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ LLPipeline::sShowHUDAttachments = TRUE;
+
+ gPipeline.resetDrawOrders();
+ mWorldViewRectRaw = window_rect;
+
+ // restore original view/camera/avatar settings settings
+ *camera = saved_camera;
+ set_current_modelview(saved_mod);
+ set_current_projection(saved_proj);
+ LLPipeline::sUseOcclusion = old_occlusion;
+
+ // ====================================================
+ return true;
+}
+
void LLViewerWindow::destroyWindow()
{
if (mWindow)
@@ -5923,7 +6051,7 @@ void LLPickInfo::fetchResults()
}
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
- NULL, -1, mPickTransparent, mPickRigged, &face_hit,
+ NULL, -1, mPickTransparent, mPickRigged, mPickUnselectable, &face_hit,
&intersection, &uv, &normal, &tangent, &start, &end);
mPickPt = mMousePt;
@@ -6068,7 +6196,7 @@ void LLPickInfo::getSurfaceInfo()
if (objectp)
{
if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
- objectp, -1, mPickTransparent, mPickRigged,
+ objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable,
&mObjectFace,
&intersection,
&mSTCoords,
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 979a560508..387a2cb06f 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -68,6 +68,8 @@ class LLWindowListener;
class LLViewerWindowListener;
class LLVOPartGroup;
class LLPopupView;
+class LLCubeMap;
+class LLCubeMapArray;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -360,6 +362,20 @@ public:
BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+
+ // take a cubemap snapshot
+ // origin - vantage point to take the snapshot from
+ // cubearray - cubemap array for storing the results
+ // index - cube index in the array to use (cube index, not face-layer)
+ // face - which cube face to update
+ // near_clip - near clip setting to use
+ BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars);
+
+
+ // special implementation of simpleSnapshot for reflection maps
+ BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
+
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
@@ -389,7 +405,7 @@ public:
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
BOOL pick_unselectable = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE);
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
LLVector4a* intersection);
@@ -398,6 +414,7 @@ public:
S32 this_face = -1,
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL,
LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b8ebe92430..72c3e03104 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject
*
@@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32;
// Should probably be 4 or 3, but didn't want to change it while change other logic - SJB
const S32 SWITCH_TO_BAKED_DISCARD = 5;
-const F32 FOOT_COLLIDE_FUDGE = 0.04f;
-
const F32 HOVER_EFFECT_MAX_SPEED = 3.f;
const F32 HOVER_EFFECT_STRENGTH = 0.f;
const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;
@@ -585,7 +583,6 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
BOOL LLVOAvatar::sDebugInvisible = FALSE;
BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
-BOOL LLVOAvatar::sShowFootPlane = FALSE;
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
@@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const
void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
{
+ if (gDisconnected)
+ {
+ // If we disconected, these values are likely to be invalid and
+ // avString() might crash due to a dead sAvatarDictionary
+ return;
+ }
+
LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
<< "sec ]"
<< avString()
@@ -1777,6 +1780,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1883,6 +1887,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1913,7 +1918,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -2810,6 +2815,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update)
{
U32 draw_order = 0;
+ S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -2849,7 +2855,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
// if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ if (attachment_selected)
{
gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
}
@@ -4105,8 +4111,7 @@ void LLVOAvatar::computeUpdatePeriod()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
&& (sLimitNonImpostors || visually_muted)
- && !mNeedsAnimUpdate
- && !sFreezeCounter)
+ && !mNeedsAnimUpdate)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@@ -4619,7 +4624,12 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent)
}
else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
{
- getOffObject();
+ // If we are starting up, motion might be loading
+ LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
+ if (!motionp || !mMotionController.isMotionLoading(motionp))
+ {
+ getOffObject();
+ }
}
//--------------------------------------------------------------------
@@ -5074,42 +5084,6 @@ U32 LLVOAvatar::renderSkinned()
return num_indices;
}
- // render collision normal
- // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due
- // to DEV-14477. the code is left here to aid in tracking down the cause
- // of the crash in the future. -brad
- if (sShowFootPlane && mDrawable.notNull())
- {
- LLVector3 slaved_pos = mDrawable->getPositionAgent();
- LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
- F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW];
- LLVector3 collide_point = slaved_pos;
- collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
-
- gGL.begin(LLRender::LINES);
- {
- F32 SQUARE_SIZE = 0.2f;
- gGL.color4f(1.f, 0.f, 0.f, 1.f);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
-
- }
- gGL.end();
- gGL.flush();
- }
//--------------------------------------------------------------------
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
@@ -6174,7 +6148,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
- jointp = mRoot->findJoint(name);
+ if (mJointAliasMap.empty())
+ {
+ getJointAliases();
+ }
+ joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
+ std::string canonical_name;
+ if (alias_iter != mJointAliasMap.end())
+ {
+ canonical_name = alias_iter->second;
+ }
+ else
+ {
+ canonical_name = name;
+ }
+ jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp;
}
else
@@ -7226,6 +7214,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
}
//-----------------------------------------------------------------------------
+// hideHair()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::hideHair()
+{
+ mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE);
+}
+
+//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
void LLVOAvatar::hideSkirt()
@@ -10230,23 +10226,6 @@ LLHost LLVOAvatar::getObjectHost() const
}
}
-//static
-void LLVOAvatar::updateFreezeCounter(S32 counter)
-{
- if(counter)
- {
- sFreezeCounter = counter;
- }
- else if(sFreezeCounter > 0)
- {
- sFreezeCounter--;
- }
- else
- {
- sFreezeCounter = 0;
- }
-}
-
BOOL LLVOAvatar::updateLOD()
{
if (mDrawable.isNull())
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3c3decaad6..df3eebee2c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -164,6 +164,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -174,6 +175,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -326,7 +328,6 @@ public:
static bool sLimitNonImpostors; // use impostors for far away avatars
static F32 sRenderDistance; // distance at which avatars will render.
static BOOL sShowAnimationDebug; // show animation debug info
- static BOOL sShowFootPlane; // show foot collision plane reported by server
static BOOL sShowCollisionVolumes; // show skeletal collision volumes
static BOOL sVisibleInFirstPerson;
static S32 sNumLODChangesThisFrame;
@@ -618,14 +619,6 @@ private:
BOOL mCulled;
//--------------------------------------------------------------------
- // Freeze counter
- //--------------------------------------------------------------------
-public:
- static void updateFreezeCounter(S32 counter = 0);
-private:
- static S32 sFreezeCounter;
-
- //--------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------
public:
@@ -808,6 +801,7 @@ public:
void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
void processAvatarAppearance(LLMessageSystem* mesgsys);
void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params);
+ void hideHair();
void hideSkirt();
void startAppearanceAnimation();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 4080a61fb0..d8b82d3114 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -67,6 +67,7 @@
#include "llsdserialize.h"
#include "llcallstack.h"
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -2661,6 +2662,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
{
if (isAgentAvatarValid())
{
+ LLUIUsage::instance().logCommand("Avatar.CustomizeStart");
if (!gAgentAvatarp->mEndCustomizeCallback.get())
{
gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index db8ad183f0..55fc663496 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -366,15 +366,6 @@ void LLVOCacheEntry::updateDebugSettings()
}
timer.reset();
- //the number of frames invisible objects stay in memory
- static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
- sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum
-
- //min radius: all objects within this radius remain loaded in memory
- static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
- sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance
- sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m
-
//objects within the view frustum whose visible area is greater than this threshold will be loaded
static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
sFrontPixelThreshold = front_pixel_threshold;
@@ -384,29 +375,38 @@ void LLVOCacheEntry::updateDebugSettings()
sRearPixelThreshold = rear_pixel_threshold;
sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
- // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
- static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
- sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m
- sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius".
- sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance.
-
- //make the above parameters adaptive to memory usage
+ //make parameters adaptive to memory usage
//starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
LLMemory::updateMemoryInfo() ;
U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
- allocated_mem /= 1024; //convert to MB.
- if(allocated_mem < low_mem_bound_MB)
- {
- return;
- }
- F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB));
-
- sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f]
- sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64]
- sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f);
+ static const F32 KB_to_MB = 1.f / 1024.f;
+ U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
+ const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB;
+ const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1]
+
+ //min radius: all objects within this radius remain loaded in memory
+ static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
+ static const F32 MIN_RADIUS = 1.0f;
+ const F32 draw_radius = gAgentCamera.mDrawDistance;
+ const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
+ sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
+
+ // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
+ static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
+ const F32 min_radius_plus_one = sNearRadius + 1.f;
+ const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance;
+ const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
+ sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);
+
+ //the number of frames invisible objects stay in memory
+ static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
+ static const U32 MIN_FRAMES = 10;
+ static const U32 MAX_FRAMES = 64;
+ const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
+ sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
//static
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 9a41eedb54..36d66cccef 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -594,7 +594,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -602,7 +602,7 @@ LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
mDepthMask = TRUE;
mSlopRatio = 0.1f;
mRenderPass = LLRenderPass::PASS_GRASS;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
}
void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
@@ -626,7 +626,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
if (drawablep->isAnimating())
{
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
+ group->mBufferUsage = GL_STREAM_DRAW;
}
U32 count = 0;
@@ -758,7 +758,7 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 5634e048eb..63876dc099 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -79,6 +79,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 52a6395618..28bd5a3c97 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -93,7 +93,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
if (!face->getVertexBuffer())
{
face->setSize(5, 12);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to "
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index f971554c9d..b0eb8d962c 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string
mReceivedCall(FALSE)
{
// make sure URI reflects encoded version of other user's agent id
- // *NOTE: in case of Avaline call generated SIP URL will be incorrect.
- // But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call
setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
}
@@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
else
{
LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL;
- // In the case of an incoming AvaLine call, the generated URI will be different from the
- // original one. This is because the P2P URI is based on avatar UUID but Avaline is not.
// See LLVoiceClient::sessionAddedEvent()
setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
}
@@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state)
void LLVoiceChannelP2P::addToTheRecentPeopleList()
{
- bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType();
-
- if (avaline_call)
- {
- LLSD call_data;
- std::string call_number = LLVoiceChannel::getSessionName();
-
- call_data["avaline_call"] = true;
- call_data["session_id"] = mSessionID;
- call_data["call_number"] = call_number;
- call_data["date"] = LLDate::now();
-
- LLRecentPeople::instance().add(mOtherUserID, call_data);
- }
- else
- {
- LLRecentPeople::instance().add(mOtherUserID);
- }
+ LLRecentPeople::instance().add(mOtherUserID);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index e2bd1a39c7..2ef2d66f18 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,6 +37,7 @@
#include "llui.h"
#include "llkeyboard.h"
#include "llagent.h"
+#include "lluiusage.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -200,6 +201,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
LLVoiceVersionInfo result;
result.serverVersion = std::string();
result.serverType = std::string();
+ result.mBuildVersion = std::string();
return result;
}
}
@@ -602,6 +604,10 @@ void LLVoiceClient::setMuteMic(bool muted)
void LLVoiceClient::setUserPTTState(bool ptt)
{
+ if (ptt)
+ {
+ LLUIUsage::instance().logCommand("Agent.EnableMicrophone");
+ }
mUserPTTState = ptt;
updateMicMuteLogic();
mMicroChangedSignal();
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index cf527a4464..246883b611 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -95,6 +95,7 @@ struct LLVoiceVersionInfo
{
std::string serverType;
std::string serverVersion;
+ std::string mBuildVersion;
};
//////////////////////////////////
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 6e08a2ff12..34e561174c 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -356,7 +356,7 @@ void LLVoiceVisualizer::render()
//---------------------------------------------------------------
LLGLSPipelineAlpha alpha_blend;
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
//-------------------------------------------------------------
// create coordinates of the geometry for the dot
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 19036a3f77..ac6369e4e2 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro()
// surviving longer than LLVivoxVoiceClient
voiceControlStateMachine(state);
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (const LLContinueError&)
{
LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient");
@@ -1606,13 +1610,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
}
else
{
- LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
-
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (channel != NULL)
+ {
+ if (channel->getSessionName().empty() && channel->getSessionID().isNull())
+ {
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
+ }
+ }
}
}
else
{
- LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL;
+ }
}
// set the spatial channel. If no voice credentials or uri are
@@ -4572,6 +4596,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
+void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id)
+{
+ // We don't generally need to process this. However, one occurence is when we first connect, and so it is the
+ // earliest opportunity to learn what we're connected to.
+ if (statusCode)
+ {
+ LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode <<
+ "statusString: " << statusString << LL_ENDL;
+ return;
+ }
+ if (build_id.empty())
+ {
+ return;
+ }
+ mVoiceVersion.mBuildVersion = build_id;
+}
+
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
@@ -4758,7 +4799,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions()
if ((*it).expired())
{
LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL;
- mSession.erase(it++);
+ it = mSession.erase(it);
}
else
++it;
@@ -6815,7 +6856,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id)
if (list_iter->second == id)
{
LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL;
- mVoiceFontList.erase(list_iter++);
+ list_iter = mVoiceFontList.erase(list_iter);
mVoiceFontListDirty = true;
}
else
@@ -7554,6 +7595,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
connectorHandle = string;
else if (!stricmp("VersionID", tag))
versionID = string;
+ else if (!stricmp("Version", tag))
+ mBuildID = string;
else if (!stricmp("AccountHandle", tag))
accountHandle = string;
else if (!stricmp("State", tag))
@@ -7856,7 +7899,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
}
else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
- { // Yet another ignored event
+ {
+ LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);
}
else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))
{
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index cf30a4e86a..ebc3a62c35 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -465,6 +465,7 @@ protected:
void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);
void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
+ void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id);
void auxAudioPropertiesEvent(F32 energy);
void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
@@ -969,6 +970,7 @@ protected:
std::string actionString;
std::string connectorHandle;
std::string versionID;
+ std::string mBuildID;
std::string accountHandle;
std::string sessionHandle;
std::string sessionGroupHandle;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 068e8a131d..08f10a2028 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -65,7 +65,7 @@ void LLVOPartGroup::restoreGL()
{
//TODO: optimize out binormal mask here. Specular and normal coords as well.
- sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW);
U32 count = LL_MAX_PARTICLE_COUNT;
if (!sVB->allocateBuffer(count*4, count*6, true))
{
@@ -485,6 +485,7 @@ BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -737,7 +738,7 @@ U32 LLVOPartGroup::getPartitionType() const
}
LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp)
{
mRenderPass = LLRenderPass::PASS_ALPHA;
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
@@ -756,6 +757,7 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_GPU_ZONE("particle vbo");
if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
return;
@@ -845,9 +847,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
- U32 index_count = 0;
- U32 vertex_count = 0;
-
group->clearDrawMap();
LLVertexBuffer* buffer = group->mVertexBuffer;
@@ -913,9 +912,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
llassert(facep->getIndicesCount() == 6);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
-
S32 idx = draw_vec.size()-1;
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 4e4d6e609d..a45d381dfa 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -74,6 +74,7 @@ public:
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 01312d65cc..9f43fb9b82 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -531,7 +531,7 @@ void LLVOSky::initCubeMap()
images.push_back(mShinyTex[side].getImageRaw());
}
- if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
mCubeMap = new LLCubeMap(false);
}
@@ -576,7 +576,7 @@ void LLVOSky::restoreGL()
updateDirections(psky);
- if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
initCubeMap();
}
@@ -660,9 +660,7 @@ void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
void LLVOSky::forceSkyUpdate()
{
mForceUpdate = TRUE;
-
- memset(&m_lastAtmosphericsVars, 0x00, sizeof(AtmosphericsVars));
-
+ m_lastAtmosphericsVars = {};
mCubeMapUpdateStage = -1;
}
@@ -1012,7 +1010,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
face->setSize(4, 6);
face->setGeomIndex(0);
face->setIndicesIndex(0);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW);
buff->allocateBuffer(4, 6, TRUE);
face->setVertexBuffer(buff);
@@ -1141,7 +1139,7 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
if (!facep->getVertexBuffer())
{
facep->setSize(4, 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
@@ -1381,7 +1379,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
{
face->setSize(quads * 4, quads * 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index b0af565867..69ae3cf23b 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -51,7 +51,7 @@ class LLVertexBufferTerrain : public LLVertexBuffer
{
public:
LLVertexBufferTerrain() :
- LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB)
+ LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW)
{
//texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1
};
@@ -880,7 +880,7 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1001,7 +1001,7 @@ U32 LLVOSurfacePatch::getPartitionType() const
}
LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mOcclusionEnabled = FALSE;
mInfiniteFarClip = TRUE;
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 884dbb3be3..aed67162d1 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -85,6 +85,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 493162b47b..b6f8d162ba 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -921,7 +921,7 @@ void LLVOTree::updateMesh()
LLFace* facep = mDrawable->getFace(0);
if (!facep) return;
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW);
if (!buff->allocateBuffer(vert_count, index_count, TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to "
@@ -1170,7 +1170,7 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1226,7 +1226,7 @@ U32 LLVOTree::getPartitionType() const
}
LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
mPartitionType = LLViewerRegion::PARTITION_TREE;
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 93c22d2da3..996e970cf8 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -111,6 +111,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f7678f5f26..663dd2d9ec 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,6 +88,7 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
+#include "llgltfmateriallist.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@@ -105,7 +106,7 @@ S32 LLVOVolume::mRenderComplexity_current = 0;
LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
-extern BOOL gGLDebugLoggingEnabled;
+extern BOOL gCubeSnapshot;
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
@@ -232,6 +233,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mMediaImplList.resize(getNumTEs());
mLastFetchedMediaVersion = -1;
+ mServerDrawableUpdateCount = 0;
memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mMDCImplCount = 0;
mLastRiggingInfoLOD = -1;
@@ -327,6 +329,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
LLColor4U color;
const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
+ const bool previously_volume_changed = mVolumeChanged;
+ const bool previously_face_mapping_changed = mFaceMappingChanged;
+ const bool previously_color_changed = mColorChanged;
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -550,9 +555,31 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// ...and clean up any media impls
cleanUpMediaImpls();
+ if ((
+ (mVolumeChanged && !previously_volume_changed) ||
+ (mFaceMappingChanged && !previously_face_mapping_changed) ||
+ (mColorChanged && !previously_color_changed)
+ )
+ && !mLODChanged) {
+ onDrawableUpdateFromServer();
+ }
+
return retval;
}
+// Called when a volume, material, etc is updated by the server, possibly by a
+// script. If this occurs too often for this object, mark it as active so that
+// it doesn't disrupt the octree/render batches, thereby potentially causing a
+// big performance penalty.
+void LLVOVolume::onDrawableUpdateFromServer()
+{
+ constexpr U32 UPDATES_UNTIL_ACTIVE = 8;
+ ++mServerDrawableUpdateCount;
+ if (mDrawable && !mDrawable->isActive() && mServerDrawableUpdateCount > UPDATES_UNTIL_ACTIVE)
+ {
+ mDrawable->makeActive();
+ }
+}
void LLVOVolume::animateTextures()
{
@@ -717,7 +744,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
// Update the pixel area of all faces
- if (mDrawable.isNull())
+ if (mDrawable.isNull() || gCubeSnapshot)
{
return;
}
@@ -982,7 +1009,12 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
// Add it to the pipeline mLightSet
gPipeline.setLight(mDrawable, TRUE);
}
-
+
+ if (isReflectionProbe())
+ {
+ updateReflectionProbePtr();
+ }
+
updateRadius();
bool force_update = true; // avoid non-alpha mDistance update being optimized away
mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
@@ -1090,27 +1122,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
- (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
-
- if (cache_in_vram)
- { //this volume might be used as source data for a transform object, put it in vram
- LLVolume* volume = getVolume();
- for (S32 i = 0; i < volume->getNumFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- if (face.mVertexBuffer.notNull())
- { //already cached
- break;
- }
- volume->genTangents(i);
- LLFace::cacheFaceInVRAM(face);
- }
- }
-
- return TRUE;
+ return TRUE;
}
else if (NO_LOD == lod)
{
@@ -1670,7 +1682,7 @@ void LLVOVolume::regenFaces()
}
}
-BOOL LLVOVolume::genBBoxes(BOOL force_global)
+BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED;
BOOL res = TRUE;
@@ -1689,7 +1701,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
// updates needed, set REBUILD_RIGGED accordingly.
// Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about.
- updateRiggedVolume();
+ updateRiggedVolume(false);
}
LLVolume* volume = mRiggedVolume;
@@ -1746,20 +1758,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
}
}
- bool rigged = false;
-
- if (!isAnimatedObject())
- {
- rigged = isRiggedMesh() && isAttachment();
- }
- else
- {
- rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying;
- }
-
if (any_valid_boxes)
{
- if (rebuild)
+ if (rebuild && should_update_octree_bounds)
{
//get the Avatar associated with this object if it's rigged
LLVOAvatar* avatar = nullptr;
@@ -1921,7 +1922,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity)
}
}
-bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
+bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool regen_faces = false;
@@ -1953,6 +1954,9 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
}
compiled = TRUE;
+ // new_lod > old_lod breaks a feedback loop between LOD updates and
+ // bounding box updates.
+ should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod;
sNumLODChanges += new_num_faces;
if ((S32)getNumTEs() != getVolume()->getNumFaces())
@@ -1991,7 +1995,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
{
- updateRiggedVolume();
+ updateRiggedVolume(false);
genBBoxes(FALSE);
mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
}
@@ -2012,8 +2016,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
group->dirtyMesh();
}
- BOOL compiled = FALSE;
-
updateRelativeXform();
if (mDrawable.isNull()) // Not sure why this is happening, but it is...
@@ -2021,49 +2023,55 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return TRUE; // No update to complete
}
+ BOOL compiled = FALSE;
+ // This should be true in most cases, unless we're sure no octree update is
+ // needed.
+ BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3();
+
if (mVolumeChanged || mFaceMappingChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
bool was_regen_faces = false;
+ should_update_octree_bounds = true;
if (mVolumeChanged)
{
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
drawable->setState(LLDrawable::REBUILD_VOLUME);
}
else if (mSculptChanged || mLODChanged || mColorChanged)
{
compiled = TRUE;
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
}
if (!was_regen_faces) {
regenFaces();
}
-
- genBBoxes(FALSE);
}
else if (mLODChanged || mSculptChanged || mColorChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
- lodOrSculptChanged(drawable, compiled);
+ lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
{
updateRiggedVolume(false);
}
- genBBoxes(FALSE);
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
else
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
- genBBoxes(FALSE);
}
+ // Generate bounding boxes if needed, and update the object's size in the
+ // octree
+ genBBoxes(FALSE, should_update_octree_bounds);
+
// Update face flags
updateFaceFlags();
@@ -2154,7 +2162,8 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
return ;
}
-//virtual
+
+//virtual
void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
{
BOOL changed = (mTEImages[index] != imagep);
@@ -2601,6 +2610,24 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
return TEM_CHANGE_TEXTURE;
}
+S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat)
+{
+ S32 retval = LLViewerObject::setTEGLTFMaterialOverride(te, mat);
+
+ if (retval == TEM_CHANGE_TEXTURE)
+ {
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+
+ return retval;
+}
+
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -2634,6 +2661,7 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
return res;
}
+
void LLVOVolume::updateTEData()
{
/*if (mDrawable.notNull())
@@ -3386,6 +3414,11 @@ F32 LLVOVolume::getSpotLightPriority() const
void LLVOVolume::updateSpotLightPriority()
{
+ if (gCubeSnapshot)
+ {
+ return;
+ }
+
F32 r = getLightRadius();
LLVector3 pos = mDrawable->getPositionAgent();
@@ -3488,6 +3521,129 @@ F32 LLVOVolume::getLightCutoff() const
}
}
+BOOL LLVOVolume::isReflectionProbe() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+}
+
+void LLVOVolume::setIsReflectionProbe(BOOL is_probe)
+{
+ BOOL was_probe = isReflectionProbe();
+ if (is_probe != was_probe)
+ {
+ if (is_probe)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, FALSE, true);
+ }
+ }
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getAmbiance() != ambiance)
+ {
+ param_block->setAmbiance(ambiance);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getClipDistance() != near_clip)
+ {
+ param_block->setClipDistance(near_clip);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeIsBox(bool is_box)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsBox() != is_box)
+ {
+ param_block->setIsBox(is_box);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsDynamic() != is_dynamic)
+ {
+ param_block->setIsDynamic(is_dynamic);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ }
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeAmbiance() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getAmbiance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeNearClip() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getClipDistance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+bool LLVOVolume::getReflectionProbeIsBox() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsBox();
+ }
+
+ return false;
+}
+
+bool LLVOVolume::getReflectionProbeIsDynamic() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsDynamic();
+ }
+
+ return false;
+}
+
U32 LLVOVolume::getVolumeInterfaceID() const
{
if (mVolumeImpl)
@@ -4076,7 +4232,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
}
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
+ if (face->isInAlphaPool())
{
alpha = 1;
}
@@ -4373,6 +4529,23 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
gPipeline.setLight(mDrawable, is_light);
}
}
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::updateReflectionProbePtr()
+{
+ if (isReflectionProbe())
+ {
+ if (mReflectionProbe.isNull())
+ {
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
+ }
+ }
+ else if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe = nullptr;
+ }
}
void LLVOVolume::setSelected(BOOL sel)
@@ -4423,7 +4596,7 @@ F32 LLVOVolume::getBinRadius()
{
LLFace* face = mDrawable->getFace(i);
if (!face) continue;
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
+ if (face->isInAlphaPool() &&
!face->canRenderAsMask())
{
alpha_wrap = TRUE;
@@ -4572,7 +4745,7 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -4583,6 +4756,14 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
return FALSE;
}
+ if (!pick_unselectable)
+ {
+ if (!LLSelectMgr::instance().canSelectObject(this))
+ {
+ return FALSE;
+ }
+ }
+
BOOL ret = FALSE;
LLVolume* volume = getVolume();
@@ -4593,7 +4774,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume(true);
+ updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
volume = mRiggedVolume;
transform = false;
}
@@ -4668,6 +4849,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
continue;
}
+ // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree.
+ // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking.
+ updateRiggedVolume(true, i, false);
face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
&p, &tc, &n, &tn);
@@ -4791,13 +4975,13 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume(bool force_update)
+void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if ((!force_update) && (!treatAsRigged()))
+ if ((!force_treat_as_rigged) && (!treatAsRigged()))
{
clearRiggedVolume();
@@ -4826,10 +5010,15 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
updateRelativeXform();
}
- mRiggedVolume->update(skin, avatar, volume);
+ mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
+void LLRiggedVolume::update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* volume,
+ FaceIndex face_index,
+ bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool copy = false;
@@ -4860,7 +5049,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
- if (frames_paused > 2)
+ if (frames_paused > 1)
{
return;
}
@@ -4879,7 +5068,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ S32 face_begin;
+ S32 face_end;
+ if (face_index == DO_NOT_UPDATE_FACES)
+ {
+ face_begin = 0;
+ face_end = 0;
+ }
+ else if (face_index == UPDATE_ALL_FACES)
+ {
+ face_begin = 0;
+ face_end = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ face_begin = face_index;
+ face_end = face_begin + 1;
+ }
+ for (S32 i = face_begin; i < face_end; ++i)
{
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@@ -4964,15 +5170,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
+ if (rebuild_face_octrees)
{
- delete dst_face.mOctree;
- dst_face.mOctree = NULL;
-
- LLVector4a size;
- size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
- size.splat(size.getLength3().getF32()*0.5f);
-
- dst_face.createOctree(1.f);
+ dst_face.destroyOctree();
+ dst_face.createOctree();
}
}
}
@@ -5001,7 +5202,7 @@ U32 LLVOVolume::getPartitionType() const
}
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp),
+: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW, regionp),
LLVolumeGeometryManager()
{
mLODPeriod = 32;
@@ -5009,7 +5210,7 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_VOLUME;
mSlopRatio = 0.25f;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
}
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
@@ -5021,7 +5222,7 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
+ mBufferUsage = GL_DYNAMIC_DRAW;
mSlopRatio = 0.25f;
}
@@ -5062,6 +5263,11 @@ bool can_batch_texture(LLFace* facep)
return false;
}
+ if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr)
+ { // PBR materials break indexed texture batching
+ return false;
+ }
+
return true;
}
@@ -5153,6 +5359,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
return;
}
+ LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type));
+
U32 passType = type;
bool rigged = facep->isState(LLFace::RIGGED);
@@ -5217,8 +5425,23 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U8 index = facep->getTextureIndex();
- LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
- LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
+ LLMaterial* mat = nullptr;
+
+ LLUUID mat_id;
+
+ auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
+ if (gltf_mat != nullptr)
+ {
+ mat_id = gltf_mat->getHash(); // TODO: cache this hash
+ }
+ else
+ {
+ mat = facep->getTextureEntry()->getMaterialParams().get();
+ if (mat)
+ {
+ mat_id = facep->getTextureEntry()->getMaterialID().asUUID();
+ }
+ }
bool batchable = false;
@@ -5240,7 +5463,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
{
- if (mat || draw_vec[idx]->mMaterial)
+ if (mat || gltf_mat || draw_vec[idx]->mMaterial)
{ //can't batch textures when materials are present (yet)
batchable = false;
}
@@ -5272,7 +5495,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- //draw_vec[idx]->mMaterial == mat &&
draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
draw_vec[idx]->mBump == bump &&
@@ -5329,11 +5551,16 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mEnvIntensity = spec;
draw_info->mSpecularMap = NULL;
draw_info->mMaterial = mat;
+ draw_info->mGLTFMaterial = gltf_mat;
draw_info->mShaderMask = shader_mask;
draw_info->mAvatar = facep->mAvatar;
draw_info->mSkinInfo = facep->mSkinInfo;
- if (mat)
+ if (gltf_mat)
+ {
+ // nothing to do, render pools will reference the GLTF material
+ }
+ else if (mat)
{
draw_info->mMaterialID = mat_id;
@@ -5495,6 +5722,8 @@ static inline void add_face(T*** list, U32* count, T* face)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+ llassert(!gCubeSnapshot);
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5579,7 +5808,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
+ useage = GL_STREAM_DRAW;
}
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -5589,6 +5818,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // apply any pending material overrides
+ gGLTFMaterialList.applyQueuedOverrides(vobj);
+
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();
@@ -5652,7 +5884,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
-
+
// Standard rigged mesh attachments:
bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
@@ -5672,6 +5904,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // HACK -- brute force this check every time a drawable gets rebuilt
+ vobj->updateTEMaterialTextures(i);
+#if 0
+#if LL_RELEASE_WITH_DEBUG_INFO
+ const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
+ const LLUUID obj_id( vobj->getID() );
+ bool is_pbr = (obj_id == pbr_id);
+#else
+ bool is_pbr = false;
+#endif
+#else
+ LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial();
+ bool is_pbr = gltf_mat != nullptr;
+#endif
+
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
// batch, it will recover its vertex buffer reference from the spatial group
facep->setVertexBuffer(NULL);
@@ -5696,7 +5943,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->isState(LLFace::RIGGED))
{
//face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
if (pool)
{
pool->removeFace(facep);
@@ -5737,6 +5984,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ type = LLDrawPool::POOL_PBR_OPAQUE;
+ }
+ else
if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
type = LLDrawPool::POOL_SIMPLE;
@@ -5801,28 +6053,39 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (gPipeline.canUseWindLightShadersOnObjects()
&& LLPipeline::sRenderBump)
{
- if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
+
+ if (LLPipeline::sRenderDeferred &&
+ (gltf_mat != nullptr || (te->getMaterialParams().notNull() && !te->getMaterialID().isNull())))
{
- LLMaterial* mat = te->getMaterialParams().get();
- if (mat->getNormalID().notNull())
- {
- if (mat->getSpecularID().notNull())
- { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
- add_face(sNormSpecFaces, normspec_count, facep);
- }
- else
- { //has normal map (needs texcoord1 and tangent)
- add_face(sNormFaces, norm_count, facep);
- }
- }
- else if (mat->getSpecularID().notNull())
- { //has specular map but no normal map, needs texcoord2
- add_face(sSpecFaces, spec_count, facep);
- }
- else
- { //has neither specular map nor normal map, only needs texcoord0
- add_face(sSimpleFaces, simple_count, facep);
- }
+ if (gltf_mat != nullptr)
+ {
+ // all gltf materials have all vertex attributes for now
+ add_face(sNormSpecFaces, normspec_count, facep);
+ }
+ else
+ {
+ LLMaterial* mat = te->getMaterialParams().get();
+ if (mat->getNormalID().notNull())
+ {
+ if (mat->getSpecularID().notNull())
+ { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
+ add_face(sNormSpecFaces, normspec_count, facep);
+ }
+ else
+ { //has normal map (needs texcoord1 and tangent)
+ add_face(sNormFaces, norm_count, facep);
+ }
+ }
+ else if (mat->getSpecularID().notNull())
+ { //has specular map but no normal map, needs texcoord2
+ add_face(sSpecFaces, spec_count, facep);
+ }
+ else
+ { //has neither specular map nor normal map, only needs texcoord0
+ add_face(sSimpleFaces, simple_count, facep);
+ }
+ }
}
else if (te->getBumpmap())
{ //needs normal + tangent
@@ -5882,7 +6145,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
drawablep->clearState(LLDrawable::RIGGED);
- vobj->updateRiggedVolume();
+ vobj->updateRiggedVolume(false);
}
}
}
@@ -5992,7 +6255,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
{
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -6026,8 +6289,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- llassert(!face->isState(LLFace::RIGGED));
-
if (!face->getGeometryVolume(*volume, face->getTEOffset(),
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
{ //something's gone wrong with the vertex buffer accounting, rebuild this group
@@ -6156,7 +6417,6 @@ struct CompareBatchBreakerRigged
}
};
-
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -6164,16 +6424,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- if (use_transform_feedback &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
- !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
- {
- buffer_usage = GL_DYNAMIC_COPY_ARB;
- }
-
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -6239,11 +6489,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
buffer_index = -1;
}
- static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
-
- //NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
- texture_index_channels = llmin(texture_index_channels, 16);
+ texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
bool flexi = false;
@@ -6405,9 +6651,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
- if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW)
{
- buffer_usage = GL_STREAM_DRAW_ARB;
+ buffer_usage = GL_STREAM_DRAW;
}
//create vertex buffer
@@ -6509,15 +6755,24 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
- LLMaterial* mat = te->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
- bool can_be_shiny = true;
- if (mat)
- {
- U8 mode = mat->getDiffuseAlphaMode();
- can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
- mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
- }
+ LLMaterial* mat = nullptr;
+ bool can_be_shiny = false;
+
+ // ignore traditional material if GLTF material is present
+ if (gltf_mat == nullptr)
+ {
+ mat = te->getMaterialParams().get();
+
+ can_be_shiny = true;
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+ }
+ }
F32 te_alpha = te->getColor().mV[3];
bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
@@ -6526,10 +6781,18 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
is_alpha = (is_alpha || transparent) ? TRUE : FALSE;
- if (mat && LLPipeline::sRenderDeferred && !hud_group)
+ if ((gltf_mat || mat) && LLPipeline::sRenderDeferred && !hud_group)
{
bool material_pass = false;
+ if (gltf_mat)
+ { // all other parameters ignored if gltf material is present
+ if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ else
+ registerFace(group, facep, LLRenderPass::PASS_PBR_OPAQUE);
+ }
+ else
// do NOT use 'fullbright' for this logic or you risk sending
// things without normals down the materials pipeline and will
// render poorly if not crash NORSPEC-240,314
@@ -6811,7 +7074,7 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
+ usage = GL_STREAM_DRAW;
}
}
@@ -6840,7 +7103,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
if (drawablep->isAnimating())
{ //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
+ usage = GL_STREAM_DRAW;
}
//for each face
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 4cb7a5481c..003ab38d64 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -65,7 +65,15 @@ public:
{
}
- void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume);
+ using FaceIndex = S32;
+ static const FaceIndex UPDATE_ALL_FACES = -1;
+ static const FaceIndex DO_NOT_UPDATE_FACES = -2;
+ void update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* src_volume,
+ FaceIndex face_index = UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
std::string mExtraDebugText;
};
@@ -114,49 +122,50 @@ public:
};
public:
- LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
+ LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ void markDead() override; // Override (and call through to parent) to clean up media references
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
+ LLDrawable* createDrawable(LLPipeline *pipeline) override;
void deleteFaces();
void animateTextures();
BOOL isVisible() const ;
- /*virtual*/ BOOL isActive() const;
- /*virtual*/ BOOL isAttachment() const;
- /*virtual*/ BOOL isRootEdit() const; // overridden for sake of attachments treating themselves as a root object
- /*virtual*/ BOOL isHUDAttachment() const;
+ BOOL isActive() const override;
+ BOOL isAttachment() const override;
+ BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
+ BOOL isHUDAttachment() const override;
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ BOOL setParent(LLViewerObject* parent);
- S32 getLOD() const { return mLOD; }
+ /*virtual*/ BOOL setParent(LLViewerObject* parent) override;
+ S32 getLOD() const override { return mLOD; }
void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
bool isNoLOD() const { return NO_LOD == mLOD; }
- const LLVector3 getPivotPositionAgent() const;
+ const LLVector3 getPivotPositionAgent() const override;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
- /*virtual*/ const LLMatrix4 getRenderMatrix() const;
+ /*virtual*/ const LLMatrix4 getRenderMatrix() const override;
typedef std::map<LLUUID, S32> texture_cost_t;
U32 getRenderCost(texture_cost_t &textures) const;
- /*virtual*/ F32 getEstTrianglesMax() const;
- /*virtual*/ F32 getEstTrianglesStreamingCost() const;
- /* virtual*/ F32 getStreamingCost() const;
- /*virtual*/ bool getCostData(LLMeshCostData& costs) const;
+ /*virtual*/ F32 getEstTrianglesMax() const override;
+ /*virtual*/ F32 getEstTrianglesStreamingCost() const override;
+ /* virtual*/ F32 getStreamingCost() const override;
+ /*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
- /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
- /*virtual*/ U32 getHighLODTriangleCount();
+ /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
+ /*virtual*/ U32 getHighLODTriangleCount() override;
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector4a* normal = NULL, // return the surface normal at the intersection point
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
+ ) override;
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
@@ -166,55 +175,59 @@ public:
BOOL getVolumeChanged() const { return mVolumeChanged; }
- /*virtual*/ F32 getRadius() const { return mVObjRadius; };
- const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
+ F32 getVObjRadius() const override { return mVObjRadius; };
+ const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
- void markForUpdate(BOOL priority);
+ void markForUpdate(BOOL priority) override;
void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
- void faceMappingChanged() { mFaceMappingChanged=TRUE; };
+ void faceMappingChanged() override { mFaceMappingChanged=TRUE; }
- /*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
+ /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
- /*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
- /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+ /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
+ /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
+
+ // update mReflectionProbe based on isReflectionProbe()
+ void updateReflectionProbePtr();
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp);
-
- /*virtual*/ void setSelected(BOOL sel);
- /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp);
-
- /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
-
- /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
- /*virtual*/ void setNumTEs(const U8 num_tes);
- /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
- /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny);
- /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright);
- /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
- /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
- /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ LLDataPacker *dp) override;
+
+ /*virtual*/ void setSelected(BOOL sel) override;
+ /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
+
+ /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
+
+ /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
+ /*virtual*/ void setNumTEs(const U8 num_tes) override;
+ /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
+ /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
+ /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
+ /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
+ /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
- /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
- /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
- /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
- /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen);
- /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media);
- /*virtual*/ BOOL setMaterial(const U8 material);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
+ S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override;
+ /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
+ /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
+ /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
+ /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
+ /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
+ /*virtual*/ BOOL setMaterial(const U8 material) override;
void setTexture(const S32 face);
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
- /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
+ /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
void updateSculptTexture();
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
void sculpt();
@@ -223,21 +236,21 @@ public:
void* user_data, S32 status, LLExtStat ext_status);
void updateRelativeXform(bool force_identity = false);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- /*virtual*/ void updateFaceSize(S32 idx);
- /*virtual*/ BOOL updateLOD();
- void updateRadius();
- /*virtual*/ void updateTextures();
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
+ /*virtual*/ void updateFaceSize(S32 idx) override;
+ /*virtual*/ BOOL updateLOD() override;
+ void updateRadius() override;
+ /*virtual*/ void updateTextures() override;
void updateTextureVirtualSize(bool forced = false);
void updateFaceFlags();
void regenFaces();
- BOOL genBBoxes(BOOL force_global);
+ BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE);
void preRebuild();
- virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
- virtual F32 getBinRadius();
+ virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
+ virtual F32 getBinRadius() override;
- virtual U32 getPartitionType() const;
+ virtual U32 getPartitionType() const override;
// For Lights
void setIsLight(BOOL is_light);
@@ -280,14 +293,27 @@ public:
F32 getLightRadius() const;
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
-
+
+ // Reflection Probes
+ void setIsReflectionProbe(BOOL is_probe);
+ void setReflectionProbeAmbiance(F32 ambiance);
+ void setReflectionProbeNearClip(F32 near_clip);
+ void setReflectionProbeIsBox(bool is_box);
+ void setReflectionProbeIsDynamic(bool is_dynamic);
+
+ BOOL isReflectionProbe() const override;
+ F32 getReflectionProbeAmbiance() const;
+ F32 getReflectionProbeNearClip() const;
+ bool getReflectionProbeIsBox() const;
+ bool getReflectionProbeIsDynamic() const;
+
// Flexible Objects
U32 getVolumeInterfaceID() const;
- virtual BOOL isFlexible() const;
- virtual BOOL isSculpted() const;
- virtual BOOL isMesh() const;
- virtual BOOL isRiggedMesh() const;
- virtual BOOL hasLightTexture() const;
+ virtual BOOL isFlexible() const override;
+ virtual BOOL isSculpted() const override;
+ virtual BOOL isMesh() const override;
+ virtual BOOL isRiggedMesh() const override;
+ virtual BOOL hasLightTexture() const override;
BOOL isVolumeGlobal() const;
@@ -304,12 +330,12 @@ public:
void onSetExtendedMeshFlags(U32 flags);
void setExtendedMeshFlags(U32 flags);
bool canBeAnimatedObject() const;
- bool isAnimatedObject() const;
- virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
- virtual void afterReparent();
+ bool isAnimatedObject() const override;
+ virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) override;
+ virtual void afterReparent() override;
//virtual
- void updateRiggingInfo();
+ void updateRiggingInfo() override;
S32 mLastRiggingInfoLOD;
// Functions that deal with media, or media navigation
@@ -362,8 +388,12 @@ public:
S32 getMDCImplCount() { return mMDCImplCount; }
- //rigged volume update (for raycasting)
- void updateRiggedVolume(bool force_update = false);
+ // Rigged volume update (for raycasting)
+ // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
+ void updateRiggedVolume(
+ bool force_treat_as_rigged,
+ LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
@@ -386,13 +416,14 @@ protected:
static S32 mRenderComplexity_last;
static S32 mRenderComplexity_current;
+ void onDrawableUpdateFromServer();
void requestMediaDataUpdate(bool isNew);
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
private:
- bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled);
+ bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds);
public:
@@ -424,6 +455,7 @@ private:
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
+ U32 mServerDrawableUpdateCount;
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 089a7712c0..6f30092326 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -152,7 +152,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
LLVertexBuffer* buff = face->getVertexBuffer();
if (!buff || !buff->isWriteable())
{
- buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
+ buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on water update to "
@@ -295,7 +295,7 @@ U32 LLVOVoidWater::getPartitionType() const
}
LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp)
{
mInfiniteFarClip = TRUE;
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index d1f584cbca..c7df343ad0 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -151,7 +151,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
if (mFsSkyVerts.isNull())
{
- mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW);
if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE))
{
@@ -216,7 +216,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
for (U32 i = 0; i < strips_segments ;++i)
{
- LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW);
mStripsVerts[i] = segment;
U32 num_stacks_this_seg = stacks_per_seg;
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ff899fe895..3cc82621c4 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -36,7 +36,7 @@
#include "llstring.h"
// newview
-#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
+#include "llavataractions.h" // for getProfileURL()
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
#include "llcorehttputil.h"
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8abb49fba8..c5aff41746 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -763,14 +763,13 @@ void LLWorld::updateParticles()
void LLWorld::renderPropertyLines()
{
S32 region_count = 0;
- S32 vertex_count = 0;
for (region_list_t::iterator iter = mVisibleRegionList.begin();
iter != mVisibleRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
region_count++;
- vertex_count += regionp->renderPropertyLines();
+ regionp->renderPropertyLines();
}
}
@@ -778,7 +777,6 @@ void LLWorld::renderPropertyLines()
void LLWorld::updateNetStats()
{
F64Bits bits;
- U32 packets = 0;
for (region_list_t::iterator iter = mActiveRegionList.begin();
iter != mActiveRegionList.end(); ++iter)
@@ -786,7 +784,6 @@ void LLWorld::updateNetStats()
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
bits += regionp->mBitsReceived;
- packets += llfloor( regionp->mPacketsReceived );
regionp->mBitsReceived = (F32Bits)0.f;
regionp->mPacketsReceived = 0.f;
}
@@ -820,7 +817,7 @@ void LLWorld::updateNetStats()
void LLWorld::printPacketsLost()
{
- LL_INFOS() << "Simulators:" << LL_ENDL;
+ LL_INFOS() << "Simulators:" << LL_ENDL;
LL_INFOS() << "----------" << LL_ENDL;
LLCircuitData *cdp = NULL;
@@ -855,6 +852,7 @@ F32 LLWorld::getLandFarClip() const
void LLWorld::setLandFarClip(const F32 far_clip)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;
static S32 const rwidth = (S32)REGION_WIDTH_U32;
S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
S32 const n2 = (llceil(far_clip) - 1) / rwidth;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 59ac4554d7..6e994b4e68 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -58,9 +58,15 @@
#include "llglheaders.h"
+// # Constants
+static const F32 MAP_DEFAULT_SCALE = 128.f;
+static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f;
+static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f;
+static const F32 MAP_ZOOM_MAX_INTERP = 0.5f;
+static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f;
+
// Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py
// Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...)
-// # Constants
// OCEAN_COLOR = "#1D475F"
const F32 OCEAN_RED = (F32)(0x1D)/255.f;
const F32 OCEAN_GREEN = (F32)(0x47)/255.f;
@@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;
-F32 LLWorldMapView::sPanX = 0.f;
-F32 LLWorldMapView::sPanY = 0.f;
-F32 LLWorldMapView::sTargetPanX = 0.f;
-F32 LLWorldMapView::sTargetPanY = 0.f;
S32 LLWorldMapView::sTrackingArrowX = 0;
S32 LLWorldMapView::sTrackingArrowY = 0;
bool LLWorldMapView::sVisibleTilesLoaded = false;
-F32 LLWorldMapView::sMapScale = 128.f;
+F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE;
+LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f);
+LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();
std::map<std::string,std::string> LLWorldMapView::sStringsMap;
@@ -166,20 +170,27 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView()
-: LLPanel(),
- mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ),
- mItemPicked(FALSE),
- mPanning( FALSE ),
- mMouseDownPanX( 0 ),
- mMouseDownPanY( 0 ),
- mMouseDownX( 0 ),
- mMouseDownY( 0 ),
- mSelectIDStart(0)
+LLWorldMapView::LLWorldMapView() :
+ LLPanel(),
+ mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)),
+ mItemPicked(FALSE),
+ mPanX(0.f),
+ mPanY(0.f),
+ mTargetPanX(0.f),
+ mTargetPanY(0.f),
+ mPanning(FALSE),
+ mMouseDownPanX(0),
+ mMouseDownPanY(0),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mSelectIDStart(0),
+ mMapScale(0.f),
+ mTargetMapScale(0.f),
+ mMapIterpTime(MAP_ITERP_TIME_CONSTANT)
{
- //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
+ // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
- clearLastClick();
+ clearLastClick();
}
BOOL LLWorldMapView::postBuild()
@@ -210,6 +221,9 @@ BOOL LLWorldMapView::postBuild()
mTextBoxNorthEast ->reshapeToFitText();
mTextBoxSouthWest->reshapeToFitText();
mTextBoxNorthWest ->reshapeToFitText();
+
+ sZoomTimer.stop();
+ setScale(sMapScaleSetting, true);
return true;
}
@@ -227,59 +241,111 @@ void LLWorldMapView::cleanupTextures()
{
}
+void LLWorldMapView::zoom(F32 zoom)
+{
+ mTargetMapScale = scaleFromZoom(zoom);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomPivot = LLVector2(0, 0);
+ sZoomTimer.start();
+ }
+}
-// static
-void LLWorldMapView::setScale( F32 scale )
+void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)
{
- if (scale != sMapScale)
- {
- F32 old_scale = sMapScale;
+ mTargetMapScale = scaleFromZoom(zoom);
+ sZoomPivot = LLVector2(x, y);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+}
- sMapScale = scale;
- if (sMapScale <= 0.f)
- {
- sMapScale = 0.1f;
- }
+F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); }
- F32 ratio = (scale / old_scale);
- sPanX *= ratio;
- sPanY *= ratio;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
- }
-}
+F32 LLWorldMapView::getScale() { return mMapScale; }
+// static
+void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }
+
+// static
+F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; }
+
+void LLWorldMapView::setScale(F32 scale, bool snap)
+{
+ if (scale != mMapScale)
+ {
+ F32 old_scale = mMapScale;
+
+ mMapScale = scale;
+ // Set the scale used when saving the setting
+ sMapScaleSetting = scale;
+ if (mMapScale <= 0.f)
+ {
+ mMapScale = 0.1f;
+ }
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ F32 ratio = (scale / old_scale);
+ mPanX *= ratio;
+ mPanY *= ratio;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
+
+ // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here
+ if (!sZoomPivot.isExactlyZero())
+ {
+ LLVector2 relative_pivot;
+ relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0);
+ relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0);
+ LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale);
+ mPanX += zoom_pan_offset.mV[VX];
+ mPanY += zoom_pan_offset.mV[VY];
+ mTargetPanX += zoom_pan_offset.mV[VX];
+ mTargetPanY += zoom_pan_offset.mV[VY];
+ }
+ }
+
+ if (snap)
+ {
+ mTargetMapScale = scale;
+ }
+}
// static
-void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y )
+void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)
{
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
}
// static
-void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap )
+void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)
{
- sTargetPanX = (F32)x;
- sTargetPanY = (F32)y;
- if (snap)
- {
- sPanX = sTargetPanX;
- sPanY = sTargetPanY;
- }
- sVisibleTilesLoaded = false;
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ mTargetPanX = (F32) x;
+ mTargetPanY = (F32) y;
+ if (snap)
+ {
+ mPanX = mTargetPanX;
+ mPanY = mTargetPanY;
+ }
+ sVisibleTilesLoaded = false;
}
-bool LLWorldMapView::showRegionInfo()
+// static
+void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time)
{
- return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false);
+ setPan(x, y, snap);
+ mMapIterpTime = interp_time;
}
+bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); }
+
///////////////////////////////////////////////////////////////////////////////////
// HELPERS
@@ -300,9 +366,28 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
- // animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
+ // animate pan if necessary
+ mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+ mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+
+ //RN: snaps to zoom value because interpolation caused jitter in the text rendering
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+ bool snap_scale = false;
+ F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME);
+ F32 current_zoom_val = zoomFromScale(mMapScale);
+ F32 target_zoom_val = zoomFromScale(mTargetMapScale);
+ F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp);
+ if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD)
+ {
+ sZoomTimer.stop();
+ snap_scale = true;
+ new_zoom_val = target_zoom_val;
+ }
+ F32 map_scale = scaleFromZoom(new_zoom_val);
+ setScale(map_scale, snap_scale);
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
@@ -310,7 +395,7 @@ void LLWorldMapView::draw()
const F32 half_height = F32(height) / 2.0f;
LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
{
@@ -347,15 +432,15 @@ void LLWorldMapView::draw()
// Find x and y position relative to camera's center.
LLVector3d rel_region_pos = origin_global - camera_global;
- F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale;
- F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale;
+ F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale;
+ F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;
// Coordinates of the sim in pixels in the UI panel
// When the view isn't panned, 0,0 = center of rectangle
- F32 bottom = sPanY + half_height + relative_y;
- F32 left = sPanX + half_width + relative_x;
- F32 top = bottom + sMapScale ;
- F32 right = left + sMapScale ;
+ F32 bottom = mPanY + half_height + relative_y;
+ F32 left = mPanX + half_width + relative_x;
+ F32 top = bottom + mMapScale ;
+ F32 right = left + mMapScale ;
// Discard if region is outside the screen rectangle (not visible on screen)
if ((top < 0.f) || (bottom > height) ||
@@ -416,7 +501,7 @@ void LLWorldMapView::draw()
if (overlayimage)
{
// Inform the fetch mechanism of the size we need
- S32 draw_size = ll_round(sMapScale);
+ S32 draw_size = ll_round(mMapScale);
overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
@@ -444,7 +529,7 @@ void LLWorldMapView::draw()
}
// Draw the region name in the lower left corner
- if (sMapScale >= DRAW_TEXT_THRESHOLD)
+ if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));
std::string mesg;
@@ -464,7 +549,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
S32_MAX, //max_chars
- sMapScale, //max_pixels
+ mMapScale, //max_pixels
NULL,
TRUE); //use ellipses
}
@@ -591,7 +676,7 @@ void LLWorldMapView::setVisible(BOOL visible)
void LLWorldMapView::drawMipmap(S32 width, S32 height)
{
// Compute the level of the mipmap to use for the current scale level
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// Set the tile boost level so that unused tiles get to 0
LLWorldMap::getInstance()->equalizeBoostLevels();
@@ -874,7 +959,7 @@ void LLWorldMapView::drawAgents()
void LLWorldMapView::drawFrustum()
{
// Draw frustum
- F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
+ F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -884,8 +969,8 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+ F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]);
+ F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -942,13 +1027,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
- pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS;
- pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;
// leave Z component in meters
- pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX;
- pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY;
+ pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX;
+ pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;
return pos_local;
}
@@ -1019,12 +1104,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
// If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well
LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
{
- x -= llfloor((getRect().getWidth() / 2 + sPanX));
- y -= llfloor((getRect().getHeight() / 2 + sPanY));
+ x -= llfloor((getRect().getWidth() / 2 + mPanX));
+ y -= llfloor((getRect().getHeight() / 2 + mPanY));
LLVector3 pos_local( (F32)x, (F32)y, 0.f );
- pos_local *= ( REGION_WIDTH_METERS / sMapScale );
+ pos_local *= ( REGION_WIDTH_METERS / mMapScale );
LLVector3d pos_global;
pos_global.setVec( pos_local );
@@ -1481,7 +1566,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
LLWorldMap::getInstance()->cancelTracking();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// If the zoom level is not too far out already, test hits
if (level <= DRAW_SIMINFO_THRESHOLD)
{
@@ -1598,8 +1683,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
- mMouseDownPanX = ll_round(sPanX);
- mMouseDownPanY = ll_round(sPanY);
+ mMouseDownPanX = ll_round(mPanX);
+ mMouseDownPanY = ll_round(mPanY);
mMouseDownX = x;
mMouseDownY = y;
sHandledLastClick = TRUE;
@@ -1614,8 +1699,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
{
// restore mouse cursor
S32 local_x, local_y;
- local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX);
- local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY);
+ local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX);
+ local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);
LLRect clip_rect = getRect();
clip_rect.stretch(-8);
clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
@@ -1643,7 +1728,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
void LLWorldMapView::updateVisibleBlocks()
{
- if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD)
+ if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)
{
// If we're zoomed out too much, we just don't load all those sim info: too much!
return;
@@ -1659,16 +1744,16 @@ void LLWorldMapView::updateVisibleBlocks()
const F32 half_height = F32(height) / 2.0f;
// Compute center into sim grid coordinates
- S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
- S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
+ S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
+ S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
// Compute the boundaries into sim grid coordinates
- S32 world_left = world_center_x - S32(half_width / sMapScale) - 1;
- S32 world_right = world_center_x + S32(half_width / sMapScale) + 1;
- S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1;
- S32 world_top = world_center_y + S32(half_height / sMapScale) + 1;
+ S32 world_left = world_center_x - S32(half_width / mMapScale) - 1;
+ S32 world_right = world_center_x + S32(half_width / mMapScale) + 1;
+ S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1;
+ S32 world_top = world_center_y + S32(half_height / mMapScale) + 1;
- //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
+ //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);
}
@@ -1689,10 +1774,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());
// Set pan to value at start of drag + offset
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
gViewerWindow->moveCursorToCenter();
}
@@ -1789,4 +1874,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
return FALSE;
}
+// static
+F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; }
+// static
+F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); }
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..ce8af76a82 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -67,12 +67,22 @@ public:
bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);
void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id);
- // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered)
- static void setScale( F32 scale );
- static void translatePan( S32 delta_x, S32 delta_y );
- static void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered)
+ // Zoom is used for UI and will interpolate the map scale over multiple frames.
+ void zoom(F32 zoom);
+ void zoomWithPivot(F32 zoom, S32 x, S32 y);
+ F32 getZoom();
+ // Scale is a linear scaling factor of in-world coordinates
+ F32 getScale();
+ // setScaleSetting/getScaleSetting are for the default map setting on login
+ static void setScaleSetting(F32 scaleSetting);
+ static F32 getScaleSetting();
+ // Pan is in pixels relative to the center of the map.
+ void translatePan( S32 delta_x, S32 delta_y );
+ void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time);
// Return true if the current scale level is above the threshold for accessing region info
- static bool showRegionInfo();
+ bool showRegionInfo();
LLVector3 globalPosToView(const LLVector3d& global_pos);
LLVector3d viewPosToGlobal(S32 x,S32 y);
@@ -153,14 +163,12 @@ public:
static LLUIImagePtr sForSaleImage;
static LLUIImagePtr sForSaleAdultImage;
- static F32 sMapScale; // scale = size of a region in pixels
-
BOOL mItemPicked;
- static F32 sPanX; // in pixels
- static F32 sPanY; // in pixels
- static F32 sTargetPanX; // in pixels
- static F32 sTargetPanY; // in pixels
+ F32 mPanX; // in pixels
+ F32 mPanY; // in pixels
+ F32 mTargetPanX; // in pixels
+ F32 mTargetPanY; // in pixels
static S32 sTrackingArrowX;
static S32 sTrackingArrowY;
static bool sVisibleTilesLoaded;
@@ -194,6 +202,19 @@ public:
private:
void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right);
+
+ void setScale(F32 scale, bool snap = true);
+
+ static F32 scaleFromZoom(F32 zoom);
+ static F32 zoomFromScale(F32 scale);
+
+ F32 mMapScale;
+ F32 mTargetMapScale;
+ static F32 sMapScaleSetting;
+ static LLVector2 sZoomPivot;
+ static LLFrameTimer sZoomTimer;
+
+ F32 mMapIterpTime;
};
#endif
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 2b400c5586..80e94c37f2 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -40,6 +40,7 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "bufferarray.h"
+#include "llversioninfo.h"
#include "llviewercontrol.h"
// Have to include these last to avoid queue redefinition!
@@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+ std::string user_agent = llformat("%s %d.%d.%d (%d)",
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
+
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
///* Setting the DNS cache timeout to -1 disables it completely.
//This might help with bug #503 */
//httpOpts->setDNSCacheTimeout(-1);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9ec3418132..b60b64ed1f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -132,12 +132,12 @@
// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
// const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2;
- const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
- const S32 WATER_REFLECT_MINIMAL = 0;
+ //const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
+ //const S32 WATER_REFLECT_MINIMAL = 0;
// const S32 WATER_REFLECT_TERRAIN = 1;
- const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
- const S32 WATER_REFLECT_AVATARS = 3;
- const S32 WATER_REFLECT_EVERYTHING = 4;
+ //const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
+ //const S32 WATER_REFLECT_AVATARS = 3;
+ //const S32 WATER_REFLECT_EVERYTHING = 4;
bool gShiftFrame = false;
@@ -203,7 +203,6 @@ F32 LLPipeline::RenderEdgeNormCutoff;
LLVector3 LLPipeline::RenderShadowGaussian;
F32 LLPipeline::RenderShadowBlurDistFactor;
bool LLPipeline::RenderDeferredAtmospheric;
-S32 LLPipeline::RenderReflectionDetail;
F32 LLPipeline::RenderHighlightFadeTime;
LLVector3 LLPipeline::RenderShadowClipPlanes;
LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
@@ -227,6 +226,7 @@ extern S32 gBoxFrame;
//extern BOOL gHideSelectedObjects;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDebugGL;
+extern BOOL gCubeSnapshot;
bool gAvatarBacklight = false;
@@ -280,29 +280,6 @@ static LLStaticHashedString sKern("kern");
static LLStaticHashedString sKernScale("kern_scale");
//----------------------------------------
-std::string gPoolNames[] =
-{
- // Correspond to LLDrawpool enum render type
- "NONE",
- "POOL_SIMPLE",
- "POOL_GROUND",
- "POOL_FULLBRIGHT",
- "POOL_BUMP",
- "POOL_MATERIALS",
- "POOL_TERRAIN,"
- "POOL_SKY",
- "POOL_WL_SKY",
- "POOL_TREE",
- "POOL_ALPHA_MASK",
- "POOL_FULLBRIGHT_ALPHA_MASK",
- "POOL_GRASS",
- "POOL_INVISIBLE",
- "POOL_AVATAR",
- "POOL_VOIDWATER",
- "POOL_WATER",
- "POOL_GLOW",
- "POOL_ALPHA"
-};
void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
@@ -338,7 +315,6 @@ bool LLPipeline::sNoAlpha = false;
bool LLPipeline::sUseTriStrips = true;
bool LLPipeline::sUseFarClip = true;
bool LLPipeline::sShadowRender = false;
-bool LLPipeline::sWaterReflections = false;
bool LLPipeline::sRenderGlow = false;
bool LLPipeline::sReflectionRender = false;
bool LLPipeline::sDistortionRender = false;
@@ -350,6 +326,8 @@ bool LLPipeline::sRenderFrameTest = false;
bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
+bool LLPipeline::sReflectionProbesEnabled = false;
+bool LLPipeline::sRenderPBR = false;
S32 LLPipeline::sVisibleLightCount = 0;
bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
@@ -363,11 +341,13 @@ void validate_framebuffer_object();
// Add color attachments for deferred rendering
// target -- RenderTarget to add attachments to
-// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions)
bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
{
- return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular
- target.addColorAttachment(GL_RGB10_A2); //normal+z
+ bool valid = true
+ && target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
+ && target.addColorAttachment(GL_RGB10_A2) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
+ && target.addColorAttachment(GL_RGBA); // frag_data[3] PBR emissive
+ return valid;
}
LLPipeline::LLPipeline() :
@@ -388,26 +368,9 @@ LLPipeline::LLPipeline() :
mGroupQ2Locked(false),
mResetVertexBuffers(false),
mLastRebuildPool(NULL),
- mAlphaPool(NULL),
- mSkyPool(NULL),
- mTerrainPool(NULL),
- mWaterPool(NULL),
- mGroundPool(NULL),
- mSimplePool(NULL),
- mGrassPool(NULL),
- mAlphaMaskPool(NULL),
- mFullbrightAlphaMaskPool(NULL),
- mFullbrightPool(NULL),
- mInvisiblePool(NULL),
- mGlowPool(NULL),
- mBumpPool(NULL),
- mMaterialsPool(NULL),
- mWLSkyPool(NULL),
mLightMask(0),
mLightMovingMask(0),
- mLightingDetail(0),
- mScreenWidth(0),
- mScreenHeight(0)
+ mLightingDetail(0)
{
mNoiseMap = 0;
mTrueNoiseMap = 0;
@@ -436,10 +399,12 @@ void LLPipeline::init()
{
refreshCachedSettings();
+ mRT = &mMainRT;
+
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -452,7 +417,8 @@ void LLPipeline::init()
stop_glerror();
//create render pass pools
- getPool(LLDrawPool::POOL_ALPHA);
+ getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
+ getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
getPool(LLDrawPool::POOL_ALPHA_MASK);
getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
@@ -462,6 +428,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_BUMP);
getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
+ getPool(LLDrawPool::POOL_PBR_OPAQUE);
resetFrameStats();
@@ -521,7 +488,7 @@ void LLPipeline::init()
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
@@ -537,8 +504,8 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
connectRefreshCachedSettingsSafe("UseOcclusion");
- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
- connectRefreshCachedSettingsSafe("RenderDeferred");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
connectRefreshCachedSettingsSafe("RenderFSAASamples");
connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
@@ -597,7 +564,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderShadowGaussian");
connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
- connectRefreshCachedSettingsSafe("RenderReflectionDetail");
connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
connectRefreshCachedSettingsSafe("RenderShadowClipPlanes");
connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes");
@@ -657,8 +623,10 @@ void LLPipeline::cleanup()
LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
}
- delete mAlphaPool;
- mAlphaPool = NULL;
+ delete mAlphaPoolPreWater;
+ mAlphaPoolPreWater = nullptr;
+ delete mAlphaPoolPostWater;
+ mAlphaPoolPostWater = nullptr;
delete mSkyPool;
mSkyPool = NULL;
delete mTerrainPool;
@@ -715,7 +683,7 @@ void LLPipeline::destroyGL()
if (mMeshDirtyQueryObject)
{
- glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ glDeleteQueries(1, &mMeshDirtyQueryObject);
mMeshDirtyQueryObject = 0;
}
}
@@ -732,8 +700,9 @@ void LLPipeline::requestResizeShadowTexture()
void LLPipeline::resizeShadowTexture()
{
- releaseShadowTargets();
- allocateShadowBuffer(mScreenWidth, mScreenHeight);
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
+ allocateShadowBuffer(mRT->width, mRT->height);
gResizeShadowTexture = FALSE;
}
@@ -744,10 +713,11 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
{
releaseScreenBuffers();
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
allocateScreenBuffer(resX,resY);
gResizeScreenTexture = FALSE;
}
@@ -767,42 +737,16 @@ void LLPipeline::allocatePhysicsBuffer()
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- bool save_settings = sRenderDeferred;
- if (save_settings)
- {
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
- if (save_settings)
- {
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
- if (ret == FBO_FAILURE)
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
- //NOTE: if the session closes successfully after this call, deferred rendering will be
- // disabled on future sessions
- if (LLPipeline::sRenderDeferred)
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LLPipeline::refreshCachedSettings();
- }
- }
-
return ret == FBO_SUCCESS_FULLRES;
}
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
@@ -856,11 +800,20 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
- refreshCachedSettings();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mRT == &mMainRT)
+ { // hacky -- allocate auxillary buffer
+ gCubeSnapshot = TRUE;
+ mRT = &mAuxillaryRT;
+ U32 res = LL_REFLECTION_PROBE_RESOLUTION * 2;
+ allocateScreenBuffer(res, res, samples);
+ mRT = &mMainRT;
+ gCubeSnapshot = FALSE;
+ }
// remember these dimensions
- mScreenWidth = resX;
- mScreenHeight = resY;
+ mRT->width = resX;
+ mRT->height = resY;
U32 res_mod = RenderResolutionDivisor;
@@ -872,7 +825,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (RenderUIBuffer)
{
- if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
+ if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
{
return false;
}
@@ -886,39 +839,33 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
const U32 occlusion_divisor = 3;
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!addDeferredAttachments(mDeferredScreen)) return false;
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ //if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!addDeferredAttachments(mRT->deferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
- if (gGLManager.mIsAMD)
- {
- screenFormat = GL_RGBA12;
- }
-
- if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
- {
- screenFormat = GL_RGBA16F_ARB;
- }
- if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ mRT->deferredScreen.shareDepthBuffer(mRT->screen);
+
if (samples > 0)
{
- if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
}
else
{
- mFXAABuffer.release();
+ mRT->fxaaBuffer.release();
}
if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
- { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa
- if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
+ { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
else
{
- mDeferredLight.release();
+ mRT->deferredLight.release();
}
allocateShadowBuffer(resX, resY);
@@ -931,24 +878,20 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
else
{
- mDeferredLight.release();
+ mRT->deferredLight.release();
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
- mFXAABuffer.release();
- mScreen.release();
- mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
- mDeferredDepth.release();
- mOcclusionDepth.release();
+ mRT->fxaaBuffer.release();
+ mRT->screen.release();
+ mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first
+ //mRT->deferredDepth.release();
+ mRT->occlusionDepth.release();
- if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
+ if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
- if (LLPipeline::sRenderDeferred)
- { //share depth buffer between deferred targets
- mDeferredScreen.shareDepthBuffer(mScreen);
- }
-
gGL.getTexUnit(0)->disable();
stop_glerror();
@@ -961,68 +904,67 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0
bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- if (LLPipeline::sRenderDeferred)
- {
- S32 shadow_detail = RenderShadowDetail;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (LLPipeline::sRenderDeferred)
+ {
+ S32 shadow_detail = RenderShadowDetail;
- const U32 occlusion_divisor = 3;
+ const U32 occlusion_divisor = 3;
- F32 scale = llmax(0.f,RenderShadowResolutionScale);
- U32 sun_shadow_map_width = BlurHappySize(resX, scale);
- U32 sun_shadow_map_height = BlurHappySize(resY, scale);
+ F32 scale = llmax(0.f, RenderShadowResolutionScale);
+ U32 sun_shadow_map_width = BlurHappySize(resX, scale);
+ U32 sun_shadow_map_height = BlurHappySize(resY, scale);
- if (shadow_detail > 0)
- { //allocate 4 sun shadow maps
- for (U32 i = 0; i < 4; i++)
- {
- if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (shadow_detail > 0)
+ { //allocate 4 sun shadow maps
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
{
return false;
}
- if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
{
return false;
}
- }
- }
- else
- {
- for (U32 i = 0; i < 4; i++)
- {
- releaseShadowTarget(i);
- }
- }
-
- U32 width = (U32) (resX*scale);
- U32 height = width;
+ }
+ }
+ else
+ {
+ for (U32 i = 0; i < 4; i++)
+ {
+ releaseSunShadowTarget(i);
+ }
+ }
- if (shadow_detail > 1)
- { //allocate two spot shadow maps
- U32 spot_shadow_map_width = width;
- U32 spot_shadow_map_height = height;
- for (U32 i = 4; i < 6; i++)
- {
- if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
- {
- return false;
- }
- if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))
- {
- return false;
- }
- }
+ if (!gCubeSnapshot) // hack to not allocate spot shadow maps during ReflectionMapManager init
+ {
+ U32 width = (U32)(resX * scale);
+ U32 height = width;
+
+ if (shadow_detail > 1)
+ { //allocate two spot shadow maps
+ U32 spot_shadow_map_width = width;
+ U32 spot_shadow_map_height = height;
+ for (U32 i = 0; i < 2; i++)
+ {
+ if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
+ {
+ return false;
+ }
+ if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ releaseSpotShadowTargets();
+ }
}
- else
- {
- for (U32 i = 4; i < 6; i++)
- {
- releaseShadowTarget(i);
- }
- }
- }
+ }
return true;
}
@@ -1036,23 +978,21 @@ void LLPipeline::updateRenderTransparentWater()
//static
void LLPipeline::updateRenderBump()
{
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump");
}
// static
void LLPipeline::updateRenderDeferred()
{
- sRenderDeferred = !gUseWireframe &&
- RenderDeferred &&
- LLRenderTarget::sUseFBO &&
- LLPipeline::sRenderBump &&
- WindLightUseAtmosShaders &&
- (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
+ sRenderPBR = sRenderDeferred;
+ static LLCachedControl<S32> sProbeDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ sReflectionProbesEnabled = sProbeDetail >= 0 && gGLManager.mGLVersion > 3.99f;
}
// static
void LLPipeline::refreshCachedSettings()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
@@ -1063,11 +1003,10 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gSavedSettings.getBOOL("UseOcclusion")
- && gGLManager.mHasOcclusionQuery) ? 2 : 0;
+ && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0;
- WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
@@ -1126,7 +1065,6 @@ void LLPipeline::refreshCachedSettings()
RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
- RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
@@ -1190,40 +1128,56 @@ void LLPipeline::releaseLUTBuffers()
LLImageGL::deleteTextures(1, &mLightFunc);
mLightFunc = 0;
}
+
+ mPbrBrdfLut.release();
}
void LLPipeline::releaseShadowBuffers()
{
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
}
void LLPipeline::releaseScreenBuffers()
{
- mUIScreen.release();
- mScreen.release();
- mFXAABuffer.release();
+ mRT->uiScreen.release();
+ mRT->screen.release();
+ mRT->fxaaBuffer.release();
mPhysicsDisplay.release();
- mDeferredScreen.release();
- mDeferredDepth.release();
- mDeferredLight.release();
- mOcclusionDepth.release();
+ mRT->deferredScreen.release();
+ mRT->deferredDepth.release();
+ mRT->deferredLight.release();
+ mRT->occlusionDepth.release();
}
-void LLPipeline::releaseShadowTarget(U32 index)
+void LLPipeline::releaseSunShadowTarget(U32 index)
{
- mShadow[index].release();
- mShadowOcclusion[index].release();
+ llassert(index < 4);
+ mRT->shadow[index].release();
+ mRT->shadowOcclusion[index].release();
}
-void LLPipeline::releaseShadowTargets()
+void LLPipeline::releaseSunShadowTargets()
{
- for (U32 i = 0; i < 6; i++)
+ for (U32 i = 0; i < 4; i++)
{
- releaseShadowTarget(i);
+ releaseSunShadowTarget(i);
}
}
+void LLPipeline::releaseSpotShadowTargets()
+{
+ if (!gCubeSnapshot) // hack to avoid freeing spot shadows during ReflectionMapManager init
+ {
+ for (U32 i = 0; i < 2; i++)
+ {
+ mSpotShadow[i].release();
+ mSpotShadowOcclusion[i].release();
+ }
+ }
+}
+
void LLPipeline::createGLBuffers()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -1231,10 +1185,9 @@ void LLPipeline::createGLBuffers()
assertInitialized();
updateRenderDeferred();
- if (LLPipeline::sWaterReflections)
+ if (LLPipeline::sRenderTransparentWater)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
- mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
}
@@ -1256,8 +1209,8 @@ void LLPipeline::createGLBuffers()
}
allocateScreenBuffer(resX, resY);
- mScreenWidth = 0;
- mScreenHeight = 0;
+ mRT->width = 0;
+ mRT->height = 0;
if (sRenderDeferred)
{
@@ -1277,7 +1230,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1292,7 +1245,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mTrueNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1357,6 +1310,21 @@ void LLPipeline::createLUTBuffers()
delete [] ls;
}
+
+ mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false);
+ mPbrBrdfLut.bindTarget();
+ gDeferredGenBrdfLutProgram.bind();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 1);
+ gGL.vertex2f(1, -1);
+ gGL.vertex2f(1, 1);
+ gGL.end();
+ gGL.flush();
+
+ gDeferredGenBrdfLutProgram.unbind();
+ mPbrBrdfLut.flush();
}
}
@@ -1573,9 +1541,12 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_MATERIALS:
poolp = mMaterialsPool;
break;
- case LLDrawPool::POOL_ALPHA:
- poolp = mAlphaPool;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ poolp = mAlphaPoolPreWater;
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ poolp = mAlphaPoolPostWater;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -1597,6 +1568,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mWLSkyPool;
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ poolp = mPBROpaquePool;
+ break;
+
default:
llassert(0);
LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
@@ -1638,6 +1613,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
LLMaterial* mat = te->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
bool color_alpha = te->getColor().mV[3] < 0.999f;
bool alpha = color_alpha;
@@ -1663,7 +1639,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
}
- if (alpha)
+ if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND))
{
return LLDrawPool::POOL_ALPHA;
}
@@ -1671,6 +1647,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
return LLDrawPool::POOL_BUMP;
}
+ else if (gltf_mat)
+ {
+ return LLDrawPool::POOL_PBR_OPAQUE;
+ }
else if (mat && !alpha)
{
return LLDrawPool::POOL_MATERIALS;
@@ -2028,6 +2008,7 @@ void LLPipeline::updateMove()
//static
F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
{
+ llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots
LLVector3 lookAt = center - camera.getOrigin();
F32 dist = lookAt.length();
@@ -2329,8 +2310,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
{
static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
- static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gGLManager.mHasOcclusionQuery;
+ static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion");
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
@@ -2353,11 +2333,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
- mOcclusionDepth.bindTarget();
+ mRT->occlusionDepth.bindTarget();
}
else
{
- mScreen.bindTarget();
+ mRT->screen.bindTarget();
}
}
@@ -2392,7 +2372,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
@@ -2438,17 +2418,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
stop_glerror();
}
- if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) &&
- !gPipeline.canUseWindLightShaders() &&
- gSky.mVOGroundp.notNull() &&
- gSky.mVOGroundp->mDrawable.notNull() &&
- !LLPipeline::sWaterReflections)
- {
- gSky.mVOGroundp->mDrawable->setVisible(camera);
- sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
- }
-
-
if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
gPipeline.canUseWindLightShaders() &&
gSky.mVOWLSkyp.notNull() &&
@@ -2479,11 +2448,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
- mOcclusionDepth.flush();
+ mRT->occlusionDepth.flush();
}
else
{
- mScreen.flush();
+ mRT->screen.flush();
}
}
}
@@ -2497,7 +2466,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
group->setVisible();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
group->updateDistance(camera);
}
@@ -2513,6 +2482,13 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
sCull->pushVisibleGroup(group);
}
+ if (group->needsUpdate() ||
+ group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+ {
+ // include this group in occlusion groups, not because it is an occluder, but because we want to run
+ // an occlusion query to find out if it's an occluder
+ markOccluder(group);
+ }
mNumVisibleNodes++;
}
@@ -2548,6 +2524,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
if (scratch_space)
{
GLint bits = 0;
+ llassert(!source.hasStencil()); // stencil buffer usage is deprecated
bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
bits |= GL_DEPTH_BUFFER_BIT;
scratch_space->copyContents(source,
@@ -2603,15 +2580,25 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot);
+#if 0
downsampleDepthBuffer(source, dest, scratch_space);
dest.bindTarget();
doOcclusion(camera);
dest.flush();
+#else
+ // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries
+ //source.bindTarget();
+ doOcclusion(camera);
+ //source.flush();
+#endif
}
void LLPipeline::doOcclusion(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("doOcclusion");
if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
@@ -2648,7 +2635,7 @@ void LLPipeline::doOcclusion(LLCamera& camera)
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -2845,7 +2832,7 @@ void LLPipeline::rebuildPriorityGroups()
void LLPipeline::rebuildGroups()
{
- if (mGroupQ2.empty())
+ if (mGroupQ2.empty() || gCubeSnapshot)
{
return;
}
@@ -2895,6 +2882,10 @@ void LLPipeline::updateGeom(F32 max_dtime)
LLPointer<LLDrawable> drawablep;
LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
assertInitialized();
@@ -3134,6 +3125,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
}
}
+ mReflectionMapManager.shift(offseta);
+
LLHUDText::shiftAll(offset);
LLHUDNameTag::shiftAll(offset);
@@ -3314,7 +3307,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
LLSpatialGroup* last_group = NULL;
BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
@@ -3396,7 +3389,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
stateSort(drawablep, camera);
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{ //avoid redundant stateSort calls
group->mLastUpdateDistance = group->mDistance;
}
@@ -3465,7 +3458,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
//if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here
{
@@ -3726,14 +3719,26 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)
void LLPipeline::touchTextures(LLDrawInfo* info)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- for (int i = 0; i < info->mTextureList.size(); ++i)
+
+ auto& mat = info->mGLTFMaterial;
+ if (mat.notNull())
{
- touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
+ touchTexture(mat->mBaseColorTexture, info->mVSize);
+ touchTexture(mat->mNormalTexture, info->mVSize);
+ touchTexture(mat->mMetallicRoughnessTexture, info->mVSize);
+ touchTexture(mat->mEmissiveTexture, info->mVSize);
}
+ else
+ {
+ for (int i = 0; i < info->mTextureList.size(); ++i)
+ {
+ touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
+ }
- touchTexture(info->mTexture, info->mVSize);
- touchTexture(info->mSpecularMap, info->mVSize);
- touchTexture(info->mNormalMap, info->mVSize);
+ touchTexture(info->mTexture, info->mVSize);
+ touchTexture(info->mSpecularMap, info->mVSize);
+ touchTexture(info->mNormalMap, info->mVSize);
+ }
}
void LLPipeline::postSort(LLCamera& camera)
@@ -3743,21 +3748,26 @@ void LLPipeline::postSort(LLCamera& camera)
assertInitialized();
LL_PUSH_CALLSTACKS();
- //rebuild drawable geometry
- for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
- {
- LLSpatialGroup* group = *i;
- if (!sUseOcclusion ||
- !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- group->rebuildGeom();
- }
- }
- LL_PUSH_CALLSTACKS();
- //rebuild groups
- sCull->assertDrawMapsEmpty();
- rebuildPriorityGroups();
+ if (!gCubeSnapshot)
+ {
+ //rebuild drawable geometry
+ for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
+ {
+ LLSpatialGroup* group = *i;
+ if (!sUseOcclusion ||
+ !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ group->rebuildGeom();
+ }
+ }
+ LL_PUSH_CALLSTACKS();
+ //rebuild groups
+ sCull->assertDrawMapsEmpty();
+
+ rebuildPriorityGroups();
+ }
+
LL_PUSH_CALLSTACKS();
@@ -3773,7 +3783,7 @@ void LLPipeline::postSort(LLCamera& camera)
continue;
}
- if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot)
{ //no way this group is going to be drawable without a rebuild
group->rebuildGeom();
}
@@ -3813,7 +3823,7 @@ void LLPipeline::postSort(LLCamera& camera)
LLDrawInfo* info = *k;
sCull->pushDrawInfo(j->first, info);
- if (!sShadowRender && !sReflectionRender)
+ if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)
{
touchTextures(info);
addTrianglesDrawn(info->mCount, info->mDrawMode);
@@ -3828,7 +3838,7 @@ void LLPipeline::postSort(LLCamera& camera)
if (alpha != group->mDrawMap.end())
{ //store alpha groups for sorting
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
if (bridge)
{
@@ -3877,11 +3887,11 @@ void LLPipeline::postSort(LLCamera& camera)
if (!mMeshDirtyQueryObject)
{
- glGenQueriesARB(1, &mMeshDirtyQueryObject);
+ glGenQueries(1, &mMeshDirtyQueryObject);
}
- glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+ glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
}*/
//pack vertex buffers for groups that chose to delay their updates
@@ -3892,7 +3902,7 @@ void LLPipeline::postSort(LLCamera& camera)
/*if (use_transform_feedback)
{
- glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
}*/
mMeshDirtyGroup.clear();
@@ -3961,7 +3971,7 @@ void LLPipeline::postSort(LLCamera& camera)
}
LL_PUSH_CALLSTACKS();
// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
- if (LLFloaterTelehub::renderBeacons())
+ if (LLFloaterTelehub::renderBeacons() && !sShadowRender)
{
LLFloaterTelehub::addBeacons();
}
@@ -4007,13 +4017,12 @@ void render_hud_elements()
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
- LLGLDisable fog(GL_FOG);
LLGLSUIDefault gls_ui;
- LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
- glStencilMask(0xFFFFFFFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gGL.color4f(1,1,1,1);
@@ -4022,7 +4031,7 @@ void render_hud_elements()
if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
// Draw the tracking overlays
@@ -4035,9 +4044,6 @@ void render_hud_elements()
}
LLViewerParcelMgr::getInstance()->render();
LLViewerParcelMgr::getInstance()->renderParcelCollision();
-
- // Render name tags.
- LLHUDObject::renderAll();
}
else if (gForceRenderLandFence)
{
@@ -4050,7 +4056,6 @@ void render_hud_elements()
}
gUIProgram.unbind();
- gGL.flush();
}
void LLPipeline::renderHighlights()
@@ -4070,14 +4075,15 @@ void LLPipeline::renderHighlights()
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
LLGLDisable test(GL_ALPHA_TEST);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
gGL.flush();
- glStencilMask(0xFFFFFFFF);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
+ // stencil ops are deprecated
+ //glStencilMask(0xFFFFFFFF);
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
- glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ //glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
+ //glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
gGL.setColorMask(false, false);
@@ -4089,8 +4095,8 @@ void LLPipeline::renderHighlights()
}
gGL.setColorMask(true, false);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // deprecated
+ //glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
//gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
@@ -4283,8 +4289,9 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;
void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
{
+#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
-
+ LL_PROFILE_GPU_ZONE("renderGeom");
assertInitialized();
F32 saved_modelview[16];
@@ -4330,7 +4337,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLGLSPipeline gls_pipeline;
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2);
@@ -4369,6 +4376,8 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
}
{
+ bool occlude = sUseOcclusion > 1;
+#if 1 // DEPRECATED -- requires forward rendering
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pools"); //LL_RECORD_BLOCK_TIME(FTM_POOLS);
// HACK: don't calculate local lights if we're rendering the HUD!
@@ -4380,7 +4389,6 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
setupHWLights(NULL);
}
- bool occlude = sUseOcclusion > 1;
U32 cur_type = 0;
pool_set_t::iterator iter1 = mPools.begin();
@@ -4402,6 +4410,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
doOcclusion(camera);
}
+
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
{
@@ -4449,17 +4458,18 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
}
iter1 = iter2;
stop_glerror();
+
}
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd");
LLVertexBuffer::unbind();
-
+#endif
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
if (occlude)
- {
+ { // catch uncommon condition where pools at drawpool grass and later are disabled
occlude = false;
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4529,19 +4539,23 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
LLGLState::checkStates();
// LLGLState::checkTextureChannels();
// LLGLState::checkClientArrays();
+#endif
}
-void LLPipeline::renderGeomDeferred(LLCamera& camera)
+void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
{
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
-
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
+ LL_PROFILE_GPU_ZONE("renderGeomDeferred");
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+
+ bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
+
{
- // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function.
- // Solutions are:
- // 1. Use a new scope
- // 2. Use named zones
- // 3. Use transient zones
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -4555,13 +4569,19 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
}
}
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
LLVertexBuffer::unbind();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
+ if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1)
+ {
+ //update reflection probe uniform
+ mReflectionMapManager.updateUniforms();
+ }
+
U32 cur_type = 0;
gGL.setColorMask(true, true);
@@ -4574,6 +4594,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
cur_type = poolp->getType();
+ if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
+ {
+ llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
+ occlude = false;
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ LLGLSLShader::bindNoShader();
+ doOcclusion(camera);
+ gGL.setColorMask(true, false);
+ }
+
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
@@ -4628,16 +4659,28 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
} // Tracy ZoneScoped
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
+ LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
calcNearbyLights(camera);
setupHWLights(NULL);
@@ -4645,7 +4688,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4653,16 +4695,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
cur_type = poolp->getType();
- if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
- {
- occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- LLGLSLShader::bindNoShader();
- doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
- gGL.setColorMask(true, false);
- }
-
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
@@ -4714,20 +4746,25 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
- if (occlude)
- {
- occlude = false;
- LLGLSLShader::bindNoShader();
- doOcclusion(camera);
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
- }
+ if (!gCubeSnapshot)
+ {
+ // debug displays
+ renderHighlights();
+ mHighlightFaces.clear();
+
+ renderDebug();
+ }
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderGeomShadow");
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4927,7 +4964,7 @@ void LLPipeline::renderDebug()
const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
gGL.setColorMask(true, true);
glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT);
gGL.setColorMask(true, false);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
@@ -5182,7 +5219,6 @@ void LLPipeline::renderDebug()
glPointSize(1.f);
}
-
// Debug stuff.
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -5236,6 +5272,12 @@ void LLPipeline::renderDebug()
visible_selected_groups.clear();
+ //draw reflection probes and links between them
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only)
+ {
+ mReflectionMapManager.renderDebug();
+ }
+
gUIProgram.bind();
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
@@ -5660,17 +5702,28 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mMaterialsPool = new_poolp;
}
break;
- case LLDrawPool::POOL_ALPHA:
- if( mAlphaPool )
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ if( mAlphaPoolPreWater )
{
llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL;
}
else
{
- mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
+ mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp;
}
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ if (mAlphaPoolPostWater)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha post-water pool" << LL_ENDL;
+ }
+ else
+ {
+ mAlphaPoolPostWater = (LLDrawPoolAlpha*)new_poolp;
+ }
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5724,6 +5777,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ if( mPBROpaquePool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL;
+ }
+ else
+ {
+ mPBROpaquePool = new_poolp;
+ }
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
@@ -5816,10 +5881,15 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mMaterialsPool = NULL;
break;
- case LLDrawPool::POOL_ALPHA:
- llassert( poolp == mAlphaPool );
- mAlphaPool = NULL;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ llassert( poolp == mAlphaPoolPreWater );
+ mAlphaPoolPreWater = nullptr;
break;
+
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ llassert(poolp == mAlphaPoolPostWater);
+ mAlphaPoolPostWater = nullptr;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5840,6 +5910,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mGroundPool = NULL;
break;
+ case LLDrawPool::POOL_PBR_OPAQUE:
+ llassert( poolp == mPBROpaquePool );
+ mPBROpaquePool = NULL;
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
@@ -5956,6 +6031,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
F32 inten = light->getLightIntensity();
if (inten < .001f)
{
@@ -5979,9 +6055,10 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
void LLPipeline::calcNearbyLights(LLCamera& camera)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
- if (LLPipeline::sReflectionRender)
+ if (LLPipeline::sReflectionRender || gCubeSnapshot)
{
return;
}
@@ -6164,6 +6241,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
void LLPipeline::setupHWLights(LLDrawPool* pool)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
LLEnvironment& environment = LLEnvironment::instance();
@@ -6171,7 +6249,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
// Ambient
LLColor4 ambient = psky->getTotalAmbient();
- gGL.setAmbientLightColor(ambient);
+
+ gGL.setAmbientLightColor(ambient);
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
@@ -6309,6 +6388,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setDiffuse(light_color);
light_state->setAmbient(LLColor4::black);
light_state->setConstantAttenuation(0.f);
+ light_state->setSize(light->getLightRadius() * 1.5f);
+ light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+
if (sRenderDeferred)
{
light_state->setLinearAttenuation(linatten);
@@ -6725,15 +6807,6 @@ void LLPipeline::toggleRenderType(U32 type)
//static
void LLPipeline::toggleRenderTypeControl(U32 type)
{
- U32 bit = (1<<type);
- if (gPipeline.hasRenderType(type))
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
- }
gPipeline.toggleRenderType(type);
}
@@ -6979,7 +7052,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, face_hit, &position, NULL, NULL, NULL);
if (hit)
{
drawable = hit;
@@ -7007,6 +7080,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
S32* face_hit,
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -7040,7 +7114,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7097,7 +7171,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
LLVector4a delta;
@@ -7185,7 +7259,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7260,6 +7334,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
mResetVertexBuffers = false;
mCubeVB = NULL;
+ mDeferredVB = NULL;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -7293,10 +7368,11 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPathingLib::getInstance()->cleanupVBOManager();
}
LLVOPartGroup::destroyGL();
+ gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
- if (LLVertexBuffer::sGLCount > 0)
+ if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
@@ -7317,6 +7393,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+ gGL.initVertexBuffer();
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+ mDeferredVB->allocateBuffer(8, 0, true);
LLVOPartGroup::restoreGL();
}
@@ -7480,15 +7560,12 @@ void LLPipeline::renderFinalize()
assertInitialized();
- if (gUseWireframe)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-
LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
+ LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2);
LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderFinalize");
+
gGL.color4f(1, 1, 1, 1);
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -7508,8 +7585,79 @@ void LLPipeline::renderFinalize()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
+ if (!gCubeSnapshot)
+ {
+ // gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLRenderTarget* screen_target = &mRT->screen;
+
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
+
+ screen_target->bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
+ if (channel > -1)
+ {
+ screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
+
+ gGL.end();
+
+ gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ screen_target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ LLVertexBuffer::unbind();
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // Render debugging beacons.
+ gObjectList.renderObjectBeacons();
+ gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
+ }
+ }
+
if (sRenderGlow)
{
+ LL_PROFILE_GPU_ZONE("glow");
mGlow[2].bindTarget();
mGlow[2].clear();
@@ -7534,7 +7682,7 @@ void LLPipeline::renderFinalize()
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
+ mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
gGL.color4f(1, 1, 1, 1);
gPipeline.enableLightsFullbright();
@@ -7550,7 +7698,7 @@ void LLPipeline::renderFinalize()
gGL.end();
- gGL.getTexUnit(0)->unbind(mScreen.getUsage());
+ gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());
mGlow[2].flush();
@@ -7628,7 +7776,7 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
+ tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight());
gGL.flush();
@@ -7636,17 +7784,18 @@ void LLPipeline::renderFinalize()
if (LLPipeline::sRenderDeferred)
{
-
bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField;
+ RenderDepthOfField &&
+ !gCubeSnapshot;
- bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
gViewerWindow->setup3DViewport();
if (dof_enabled)
{
+ LL_PROFILE_GPU_ZONE("dof");
LLGLSLShader *shader = &gDeferredPostProgram;
LLGLDisable blend(GL_BLEND);
@@ -7682,7 +7831,7 @@ void LLPipeline::renderFinalize()
LLVector4a result;
result.clear();
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
focus_point.set(result.getF32ptr());
}
@@ -7731,7 +7880,7 @@ void LLPipeline::renderFinalize()
const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
- // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+ // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
@@ -7751,15 +7900,15 @@ void LLPipeline::renderFinalize()
F32 magnification = focal_length / (subject_distance - focal_length);
{ // build diffuse+bloom+CoF
- mDeferredLight.bindTarget();
+ mRT->deferredLight.bindTarget();
shader = &gDeferredCoFProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
@@ -7782,23 +7931,23 @@ void LLPipeline::renderFinalize()
gGL.end();
unbindDeferredShader(*shader);
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
- U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
{ // perform DoF sampling at half-res (preserve alpha channel)
- mScreen.bindTarget();
+ mRT->screen.bindTarget();
glViewport(0, 0, dof_width, dof_height);
gGL.setColorMask(true, false);
shader = &gDeferredPostProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ mRT->deferredLight.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7817,15 +7966,15 @@ void LLPipeline::renderFinalize()
gGL.end();
unbindDeferredShader(*shader);
- mScreen.flush();
+ mRT->screen.flush();
gGL.setColorMask(true, true);
}
{ // combine result based on alpha
if (multisample)
{
- mDeferredLight.bindTarget();
- glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ mRT->deferredLight.bindTarget();
+ glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
}
else
{
@@ -7839,10 +7988,10 @@ void LLPipeline::renderFinalize()
shader = &gDeferredDoFCombineProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7866,24 +8015,25 @@ void LLPipeline::renderFinalize()
if (multisample)
{
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
}
}
else
{
+ LL_PROFILE_GPU_ZONE("no dof");
if (multisample)
{
- mDeferredLight.bindTarget();
+ mRT->deferredLight.bindTarget();
}
LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0, channel);
+ mRT->screen.bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -7902,17 +8052,18 @@ void LLPipeline::renderFinalize()
if (multisample)
{
- mDeferredLight.flush();
+ mRT->deferredLight.flush();
}
}
if (multisample)
{
+ LL_PROFILE_GPU_ZONE("aa");
// bake out texture2D with RGBL for FXAA shader
- mFXAABuffer.bindTarget();
+ mRT->fxaaBuffer.bindTarget();
- S32 width = mScreen.getWidth();
- S32 height = mScreen.getHeight();
+ S32 width = mRT->screen.getWidth();
+ S32 height = mRT->screen.getHeight();
glViewport(0, 0, width, height);
LLGLSLShader *shader = &gGlowCombineFXAAProgram;
@@ -7920,10 +8071,10 @@ void LLPipeline::renderFinalize()
shader->bind();
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ mRT->deferredLight.bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -7934,18 +8085,18 @@ void LLPipeline::renderFinalize()
gGL.flush();
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
shader->unbind();
- mFXAABuffer.flush();
+ mRT->fxaaBuffer.flush();
shader = &gFXAAProgram;
shader->bind();
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
if (channel > -1)
{
- mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
}
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
@@ -7954,8 +8105,8 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- F32 scale_x = (F32) width / mFXAABuffer.getWidth();
- F32 scale_y = (F32) height / mFXAABuffer.getHeight();
+ F32 scale_x = (F32) width / mRT->fxaaBuffer.getWidth();
+ F32 scale_y = (F32) height / mRT->fxaaBuffer.getHeight();
shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
@@ -7973,6 +8124,7 @@ void LLPipeline::renderFinalize()
shader->unbind();
}
}
+#if 0 // DEPRECATED
else // not deferred
{
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
@@ -8006,16 +8158,16 @@ void LLPipeline::renderFinalize()
gGlowCombineProgram.bind();
gGL.getTexUnit(0)->bind(&mGlow[1]);
- gGL.getTexUnit(1)->bind(&mScreen);
+ gGL.getTexUnit(1)->bind(&mRT->screen);
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
buff->setBuffer(mask);
buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
gGlowCombineProgram.unbind();
}
-
+#endif
gGL.setSceneBlendType(LLRender::BT_ALPHA);
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
@@ -8049,12 +8201,12 @@ void LLPipeline::renderFinalize()
gSplatTextureRectProgram.unbind();
}
- if (LLRenderTarget::sUseFBO)
- { // copy depth buffer from mScreen to framebuffer
- LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0,
- mScreen.getWidth(), mScreen.getHeight(),
+ /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot)
+ { // copy depth buffer from mRT->screen to framebuffer
+ LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0,
+ mRT->screen.getWidth(), mRT->screen.getHeight(),
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
+ }*/
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
@@ -8070,37 +8222,59 @@ void LLPipeline::renderFinalize()
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LL_PROFILE_GPU_ZONE("bindDeferredShader");
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
shader.bind();
S32 channel = 0;
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0]
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1]
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2]
}
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3]
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ mPbrBrdfLut.bindTexture(0, channel);
+ }
+
+
+#if 0
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
if (channel > -1)
{
gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
stop_glerror();
}
+#else
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ stop_glerror();
+ }
+#endif
glh::matrix4f projection = get_current_projection();
glh::matrix4f inv_proj = projection.inverse();
@@ -8155,7 +8329,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
for (U32 i = 0; i < 4; i++)
{
- LLRenderTarget* shadow_target = getShadowTarget(i);
+ LLRenderTarget* shadow_target = getSunShadowTarget(i);
if (shadow_target)
{
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
@@ -8163,39 +8337,39 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
if (channel > -1)
{
stop_glerror();
- gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE);
+ gGL.getTexUnit(channel)->bind(getSunShadowTarget(i), TRUE);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
stop_glerror();
}
}
}
- for (U32 i = 4; i < 6; i++)
- {
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i);
- stop_glerror();
- if (channel > -1)
- {
- stop_glerror();
- LLRenderTarget* shadow_target = getShadowTarget(i);
- if (shadow_target)
- {
- gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
- stop_glerror();
- }
- }
- }
+ for (U32 i = 4; i < 6; i++)
+ {
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i);
+ stop_glerror();
+ if (channel > -1)
+ {
+ stop_glerror();
+ LLRenderTarget* shadow_target = getSpotShadowTarget(i-4);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ stop_glerror();
+ }
+ }
+ }
stop_glerror();
@@ -8222,16 +8396,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
{
cube_map->enable(channel);
cube_map->bind();
- F32* m = gGLModelView;
-
- F32 mat[] = { m[0], m[1], m[2],
- m[4], m[5], m[6],
- m[8], m[9], m[10] };
-
- shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
+
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
+ bindReflectionProbes(shader);
+
if (gAtmosphere)
{
// bind precomputed textures necessary for calculating sun and sky luminance
@@ -8260,7 +8437,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
}
}
- shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ /*if (gCubeSnapshot)
+ { // we only really care about the first two values, but the shader needs increasing separation between clip planes
+ shader.uniform4f(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1.f, 64.f, 128.f, 256.f);
+ }
+ else*/
+ {
+ shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ }
shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
@@ -8295,8 +8479,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV);
- shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight());
- shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
@@ -8306,8 +8490,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
- shader.uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
- shader.uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
+ shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
+ shader.uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t sky = environment.getCurrentSky();
@@ -8329,21 +8513,25 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)
return v;
}
-void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
+void LLPipeline::renderDeferredLighting()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderDeferredLighting");
if (!sCull)
{
return;
}
- LLRenderTarget *deferred_target = &mDeferredScreen;
- LLRenderTarget *deferred_depth_target = &mDeferredDepth;
- LLRenderTarget *deferred_light_target = &mDeferredLight;
+ LLRenderTarget *screen_target = &mRT->screen;
+ //LLRenderTarget *deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget *deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
LLViewerCamera *camera = LLViewerCamera::getInstance();
+
+#if 0
{
LLGLDepthTest depth(GL_TRUE);
deferred_depth_target->copyContents(*deferred_target,
@@ -8358,8 +8546,9 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
}
+#endif
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0);
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{
@@ -8367,7 +8556,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
}
// ati doesn't seem to love actually using the stencil buffer on FBO's
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
// glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
// glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -8406,6 +8595,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (RenderDeferredSSAO || RenderShadowDetail > 0)
{
+ LL_PROFILE_GPU_ZONE("sun program");
deferred_light_target->bindTarget();
{ // paint shadow/SSAO light map (direct lighting lightmap)
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow");
@@ -8453,66 +8643,79 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
}
if (RenderDeferredSSAO)
- { // soften direct lighting lightmap
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow");
- // blur lightmap
- screen_target->bindTarget();
- glClearColor(1, 1, 1, 1);
- screen_target->clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0, 0, 0, 0);
+ {
+ /*if (gCubeSnapshot)
+ { // SSAO and shadows disabled in reflection maps
+ deferred_light_target->bindTarget();
+ glClearColor(1, 1, 1, 1);
+ deferred_light_target->clear();
+ glClearColor(0, 0, 0, 0);
+ deferred_light_target->flush();
+ }
+ else*/
+ {
+ // soften direct lighting lightmap
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow");
+ LL_PROFILE_GPU_ZONE("soften shadow");
+ // blur lightmap
+ screen_target->bindTarget();
+ glClearColor(1, 1, 1, 1);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0, 0, 0, 0);
- bindDeferredShader(gDeferredBlurLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- LLVector3 go = RenderShadowGaussian;
- const U32 kern_length = 4;
- F32 blur_size = RenderShadowBlurSize;
- F32 dist_factor = RenderShadowBlurDistFactor;
+ bindDeferredShader(gDeferredBlurLightProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ LLVector3 go = RenderShadowGaussian;
+ const U32 kern_length = 4;
+ F32 blur_size = RenderShadowBlurSize;
+ F32 dist_factor = RenderShadowBlurDistFactor;
- // sample symmetrically with the middle sample falling exactly on 0.0
- F32 x = 0.f;
+ // sample symmetrically with the middle sample falling exactly on 0.0
+ F32 x = 0.f;
- LLVector3 gauss[32]; // xweight, yweight, offset
+ LLVector3 gauss[32]; // xweight, yweight, offset
- for (U32 i = 0; i < kern_length; i++)
- {
- gauss[i].mV[0] = llgaussian(x, go.mV[0]);
- gauss[i].mV[1] = llgaussian(x, go.mV[1]);
- gauss[i].mV[2] = x;
- x += 1.f;
- }
+ for (U32 i = 0; i < kern_length; i++)
+ {
+ gauss[i].mV[0] = llgaussian(x, go.mV[0]);
+ gauss[i].mV[1] = llgaussian(x, go.mV[1]);
+ gauss[i].mV[2] = x;
+ x += 1.f;
+ }
- gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
- gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
- gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f));
+ gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+ gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f));
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
- screen_target->flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
+ screen_target->flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
- bindDeferredShader(gDeferredBlurLightProgram, screen_target);
+ bindDeferredShader(gDeferredBlurLightProgram, screen_target);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- deferred_light_target->bindTarget();
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ deferred_light_target->bindTarget();
- gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+ deferred_light_target->flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
}
- deferred_light_target->flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
}
stop_glerror();
@@ -8533,11 +8736,23 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics");
+ LL_PROFILE_GPU_ZONE("atmospherics");
bindDeferredShader(soften_shader);
LLEnvironment &environment = LLEnvironment::instance();
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+ soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+ if (!LLPipeline::sUnderWaterRender && LLPipeline::sRenderPBR)
+ {
+ soften_shader.bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, LLViewerFetchedTexture::sDefaultIrradiancePBRp); // PBR: irradiance
+ }
+
+ if(LLPipeline::sRenderPBR)
+ {
+ LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
+ soften_shader.uniform3fv(LLShaderMgr::DEFERRED_VIEW_DIR, 1, cameraAtAxis.mV);
+ }
{
LLGLDepthTest depth(GL_FALSE);
@@ -8563,9 +8778,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
+#if 0
{ // render non-deferred geometry (fullbright, alpha, etc)
LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
gPipeline.pushRenderTypeMask();
@@ -8578,8 +8794,9 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
+#endif
- bool render_local = RenderLocalLights;
+ bool render_local = RenderLocalLights; // && !gCubeSnapshot;
if (render_local)
{
@@ -8588,9 +8805,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLDrawable::drawable_list_t spot_lights;
LLDrawable::drawable_list_t fullscreen_spot_lights;
- for (U32 i = 0; i < 2; i++)
+ if (!gCubeSnapshot)
{
- mTargetShadowSpotLight[i] = NULL;
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
}
std::list<LLVector4> light_colors;
@@ -8599,11 +8819,12 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights");
+ LL_PROFILE_GPU_ZONE("local lights");
bindDeferredShader(gDeferredLightProgram);
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -8705,6 +8926,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (!spot_lights.empty())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors");
+ LL_PROFILE_GPU_ZONE("projectors");
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
@@ -8751,7 +8973,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights");
LLGLDepthTest depth(GL_FALSE);
-
+ LL_PROFILE_GPU_ZONE("fullscreen lights");
// full screen blit
gGL.pushMatrix();
gGL.loadIdentity();
@@ -8836,69 +9058,14 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
gGL.setColorMask(true, true);
}
- screen_target->flush();
-
- // gamma correct lighting
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- {
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);
-
- screen_target->bindTarget();
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
- // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- S32 channel = 0;
- channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
- if (channel > -1)
- {
- screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
-
- gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
-
- gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- screen_target->flush();
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- screen_target->bindTarget();
-
{ // render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_GLOW,
@@ -8920,30 +9087,13 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_WATER,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
popRenderTypeMask();
}
- {
- // render highlights, etc.
- renderHighlights();
- mHighlightFaces.clear();
-
- renderDebug();
-
- LLVertexBuffer::unbind();
-
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- gObjectList.resetObjectBeacons();
- gSky.addSunMoonBeacons();
- }
- }
-
screen_target->flush();
}
@@ -9037,6 +9187,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
}
+ //if (!gCubeSnapshot)
{
LLDrawable* potential = drawablep;
//determine if this is a good light for casting shadows
@@ -9088,15 +9239,18 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
stop_glerror();
shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
+ //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -9105,7 +9259,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
@@ -9113,7 +9267,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
@@ -9129,350 +9283,74 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
cube_map->disable();
}
}
+
+ unbindReflectionProbes(shader);
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->activate();
shader.unbind();
}
-inline float sgn(float a)
+void LLPipeline::setEnvMat(LLGLSLShader& shader)
{
- if (a > 0.0F) return (1.0F);
- if (a < 0.0F) return (-1.0F);
- return (0.0F);
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
-void LLPipeline::generateWaterReflection(LLCamera& camera_in)
+void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- if (!assertInitialized())
+ if (!sReflectionProbesEnabled)
{
return;
}
- if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate)
+ S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ bool bound = false;
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
{
- //disable occlusion culling for reflection/refraction passes (save setting to restore later)
- S32 occlude = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0;
-
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
-
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
-
- LLPipeline::sReflectionRender = true;
-
- gPipeline.pushRenderTypeMask();
-
- glh::matrix4f saved_modelview = get_current_modelview();
- glh::matrix4f saved_projection = get_current_projection();
- glh::matrix4f mat;
-
- S32 reflection_detail = RenderReflectionDetail;
-
- F32 water_height = gAgent.getRegion()->getWaterHeight();
- F32 camera_height = camera_in.getOrigin().mV[VZ];
- F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height);
-
- LLVector3 reflection_offset = LLVector3(0, 0, distance_to_water * 2.0f);
- LLVector3 camera_look_at = camera_in.getAtAxis();
- LLVector3 reflection_look_at = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]);
- LLVector3 reflect_origin = camera_in.getOrigin() - reflection_offset;
- LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f);
-
- camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
-
- //plane params
- LLPlane plane;
- LLVector3 pnorm;
-
- if (camera_is_underwater)
- {
- //camera is below water, cull above water
- pnorm.setVec(0, 0, 1);
- }
- else
- {
- //camera is above water, cull below water
- pnorm = LLVector3(0, 0, -1);
- }
-
- plane.setVec(LLVector3(0, 0, water_height), pnorm);
-
- if (!camera_is_underwater)
- {
- //generate planar reflection map
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- mat.set_scale(glh::vec3f(1, 1, -1));
- mat.set_translate(glh::vec3f(0,0,water_height*2.f));
- mat = saved_modelview * mat;
-
-
- mReflectionModelView = mat;
-
- set_current_modelview(mat);
- gGL.loadMatrix(mat.m);
-
- LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
-
- glh::vec3f origin(0, 0, 0);
- glh::matrix4f inv_mat = mat.inverse();
- inv_mat.mult_matrix_vec(origin);
-
- camera.setOrigin(origin.v);
-
- glCullFace(GL_FRONT);
-
- if (LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glClearColor(0,0,0,0);
- mWaterRef.bindTarget();
-
- gGL.setColorMask(true, true);
- mWaterRef.clear();
- gGL.setColorMask(true, false);
- mWaterRef.getViewport(gGLViewport);
-
- //initial sky pass (no user clip plane)
- //mask out everything but the sky
- gPipeline.pushRenderTypeMask();
- {
- if (reflection_detail >= WATER_REFLECT_MINIMAL)
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
- }
- else
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
- }
-
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- gPipeline.pushRenderTypeMask();
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
-
- if (reflection_detail > WATER_REFLECT_MINIMAL)
- { //mask out selected geometry based on reflection detail
- if (reflection_detail < WATER_REFLECT_EVERYTHING)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_AVATARS)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_STATIC_OBJECTS)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
- }
- }
- }
-
- LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
- LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, mReflectedObjects, &plane);
- stateSort(camera, mReflectedObjects);
- renderGeom(camera);
- }
- }
- gPipeline.popRenderTypeMask();
- }
-
- mWaterRef.flush();
- }
-
- glCullFace(GL_BACK);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- set_current_modelview(saved_modelview);
- }
-
- camera.setOrigin(camera_in.getOrigin());
- //render distortion map
- static bool last_update = true;
- if (last_update)
- {
- gPipeline.pushRenderTypeMask();
-
- camera.setFar(camera_in.getFar());
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- END_RENDER_TYPES);
-
- // intentionally inverted so that distortion map contents (objects under the water when we're above it)
- // will properly include water fog effects
- LLPipeline::sUnderWaterRender = !camera_is_underwater;
-
- if (LLPipeline::sUnderWaterRender)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- END_RENDER_TYPES);
- }
- LLViewerCamera::updateFrustumPlanes(camera);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- LLPipeline::sDistortionRender = true;
-
- LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
- glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-
- // HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts
- // during distortion render (doesn't break main render because the camera is the same perspective
- // as world camera and occlusion culling is disabled for this pass)
- //LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- mWaterDis.bindTarget();
- mWaterDis.getViewport(gGLViewport);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- F32 water_dist = water_height;
-
- //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
- // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
- LLPlane plane;
-
- if (camera_is_underwater)
- {
- //nudge clip plane below water to avoid visible holes in objects intersecting water surface
- water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is below water, clip plane points up
- pnorm.setVec(0, 0, -1);
- }
- else
- {
- //nudge clip plane above water to avoid visible holes in objects intersecting water surface
- water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is above water, clip plane points down
- pnorm = LLVector3(0, 0, 1);
- }
-
- plane.setVec(LLVector3(0, 0, water_dist), pnorm);
-
- LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- updateCull(camera, mRefractedObjects, &plane);
- stateSort(camera, mRefractedObjects);
- renderGeom(camera);
- }
-
- gUIProgram.bind();
-
- LLWorld::getInstance()->renderPropertyLines();
-
- gUIProgram.unbind();
-
- mWaterDis.flush();
- }
-
- LLPipeline::sDistortionRender = false;
-
- gPipeline.popRenderTypeMask();
- }
- last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
-
- gPipeline.popRenderTypeMask();
-
- LLPipeline::sUnderWaterRender = false;
- LLPipeline::sReflectionRender = false;
+ mReflectionMapManager.mTexture->bind(channel);
+ bound = true;
+ }
- LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
- LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
+ channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull())
+ {
+ mReflectionMapManager.mIrradianceMaps->bind(channel);
+ bound = true;
+ }
- if (!LLRenderTarget::sUseFBO)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- glClearColor(0.f, 0.f, 0.f, 0.f);
- gViewerWindow->setup3DViewport();
+ if (bound)
+ {
+ mReflectionMapManager.setUniforms();
- LLGLState::checkStates();
+ setEnvMat(shader);
+ }
+}
- if (!skip_avatar_update)
+void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader)
+{
+ S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP);
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
+ {
+ mReflectionMapManager.mTexture->unbind();
+ if (channel == 0)
{
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE);
}
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- // restore occlusion culling
- LLPipeline::sUseOcclusion = occlude;
}
- else
- {
- // Initial sky pass is still needed even if water reflection is not rendering
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
- if (!camera_is_underwater)
- {
- gPipeline.pushRenderTypeMask();
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+}
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
- }
- }
+inline float sgn(float a)
+{
+ if (a > 0.0F) return (1.0F);
+ if (a < 0.0F) return (-1.0F);
+ return (0.0F);
}
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -9555,7 +9433,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbri
void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
-
+ LL_PROFILE_GPU_ZONE("renderShadow");
//disable occlusion culling for shadow passes (save setting to restore later)
S32 occlude = LLPipeline::sUseOcclusion;
if (!use_occlusion)
@@ -9577,20 +9455,22 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_NORMMAP,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
- LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE
};
LLGLEnable cull(GL_CULL_FACE);
//enable depth clamping if available
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+ //LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
- LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1];
+ LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
+ mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
+ mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
occlusion_target.bindTarget();
updateCull(shadow_cam, result);
@@ -9642,7 +9522,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
-
+ LL_PROFILE_GPU_ZONE("shadow simple");
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)
{
@@ -9659,7 +9539,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
if (use_shader)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
gDeferredShadowProgram.unbind();
renderGeomShadow(shadow_cam);
@@ -9668,14 +9548,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
else
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
renderGeomShadow(shadow_cam);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
-
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha");
+ LL_PROFILE_GPU_ZONE("shadow alpha");
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
@@ -9690,19 +9570,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_TEXTURE_INDEX;
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked");
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend");
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
renderAlphaObjects(mask, TRUE, TRUE, rigged);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked");
gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
@@ -9711,7 +9591,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass");
gDeferredTreeShadowProgram.bind(rigged);
if (i == 0)
{
@@ -9724,6 +9604,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged);
renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged);
renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_PBR_OPAQUE, no_idx_mask, true, false, rigged);
}
}
}
@@ -9734,9 +9615,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1];
+ LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
+ mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
+ mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
- doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ if (occlude > 1)
+ {
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ }
if (use_shader)
{
@@ -9957,7 +9843,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)
{
mHighlightSet.insert(HighlightItem(mHighlightObject));
}
-
+ llassert(!gCubeSnapshot);
+
if (!mHighlightSet.empty())
{
F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;
@@ -10005,9 +9892,16 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
}
-LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
+LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i)
{
- return &mShadow[i];
+ llassert(i < 4);
+ return &mRT->shadow[i];
+}
+
+LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i)
+{
+ llassert(i < 2);
+ return &mSpotShadow[i];
}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
@@ -10021,6 +9915,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
+ LL_PROFILE_GPU_ZONE("generateSunShadow");
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
@@ -10045,6 +9940,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_GRASS,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_BUMP,
@@ -10103,6 +10000,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE,
+ LLPipeline::RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -10132,6 +10031,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
clip = RenderShadowOrthoClipPlanes;
mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
+ //if (gCubeSnapshot)
+ { //always do a single 64m shadow in reflection maps
+ mSunClipPlanes.set(64.f, 128.f, 256.f);
+ mSunOrthoClipPlanes.set(64.f, 128.f, 256.f);
+ }
+
//currently used for amount to extrude frusta corners for constructing shadow frusta
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
@@ -10248,28 +10153,41 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
// convenience array of 4 near clip plane distances
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
if (mSunDiffuse == LLColor4::black)
- { //sun diffuse is totally black, shadows don't matter
+ { //sun diffuse is totally shadows don't matter
LLGLDepthTest depth(GL_TRUE);
for (S32 j = 0; j < 4; j++)
{
- mShadow[j].bindTarget();
- mShadow[j].clear();
- mShadow[j].flush();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
}
}
else
{
- for (S32 j = 0; j < 4; j++)
+ /*if (gCubeSnapshot)
+ {
+ // do one shadow split for cube snapshots, clear the rest
+ mSunClipPlanes.set(64.f, 64.f, 64.f);
+ dist[1] = dist[2] = dist[3] = dist[4] = 64.f;
+ for (S32 j = 1; j < 4; j++)
+ {
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
+ }
+ }*/
+
+ //for (S32 j = 0; j < (gCubeSnapshot ? 1 : 4); j++)
+ for (S32 j = 0; j < 4; j++)
{
if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
{
mShadowFrustPoints[j].clear();
}
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
//restore render matrices
set_current_modelview(saved_view);
@@ -10323,12 +10241,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowCamera[j+4] = shadow_cam;
}
- mShadow[j].bindTarget();
+ mRT->shadow[j].bindTarget();
{
LLGLDepthTest depth(GL_TRUE);
- mShadow[j].clear();
+ mRT->shadow[j].clear();
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
mShadowError.mV[j] = 0.f;
mShadowFOV.mV[j] = 0.f;
@@ -10615,18 +10533,18 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
stop_glerror();
- mShadow[j].bindTarget();
- mShadow[j].getViewport(gGLViewport);
- mShadow[j].clear();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].getViewport(gGLViewport);
+ mRT->shadow[j].clear();
- U32 target_width = mShadow[j].getWidth();
+ U32 target_width = mRT->shadow[j].getWidth();
{
static LLCullResult result[4];
renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
@@ -10641,142 +10559,150 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (gen_shadow)
{
- LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
- F32 fade_amt = gFrameIntervalSeconds.value()
- * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
+ //update shadow targets
+ for (U32 i = 0; i < 2; i++)
+ { //for each current shadow
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
+
+ if (mShadowSpotLight[i].notNull() &&
+ (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+ mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+ { //keep this spotlight
+ mSpotLightFade[i] = llmin(mSpotLightFade[i] + fade_amt, 1.f);
+ }
+ else
+ { //fade out this light
+ mSpotLightFade[i] = llmax(mSpotLightFade[i] - fade_amt, 0.f);
- if (mShadowSpotLight[i].notNull() &&
- (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
- mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
- { //keep this spotlight
- mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
- }
- else
- { //fade out this light
- mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-
- if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
- { //faded out, grab one of the pending spots (whichever one isn't already taken)
- if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[0];
- }
- else
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[1];
- }
- }
- }
- }
+ if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+ { //faded out, grab one of the pending spots (whichever one isn't already taken)
+ if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i + 1) % 2])
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+ }
+ else
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ }
+ }
+ }
+ }
+ }
- for (S32 i = 0; i < 2; i++)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ for (S32 i = 0; i < 2; i++)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- if (mShadowSpotLight[i].isNull())
- {
- continue;
- }
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- LLDrawable* drawable = mShadowSpotLight[i];
+ LLDrawable* drawable = mShadowSpotLight[i];
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f);
+ at_axis *= quat;
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ LLVector3 np = center + at_axis;
+ at_axis.normVec();
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f);
- LLVector3 origin = np - at_axis*dist;
+ LLVector3 origin = np - at_axis * dist;
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ view[i + 4] = glh::matrix4f((F32*)mat.mMatrix);
- view[i+4] = view[i+4].inverse();
+ view[i + 4] = view[i + 4].inverse();
- //get perspective matrix
- F32 near_clip = dist+0.01f;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = dist+volume->getLightRadius()*1.5f;
+ //get perspective matrix
+ F32 near_clip = dist + 0.01f;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = dist + volume->getLightRadius() * 1.5f;
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width / height;
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- set_current_modelview(view[i+4]);
- set_current_projection(proj[i+4]);
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
- mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-
- for (U32 j = 0; j < 16; j++)
- {
- gGLLastModelView[j] = mShadowModelview[i+4].m[j];
- gGLLastProjection[j] = mShadowProjection[i+4].m[j];
- }
+ set_current_modelview(view[i + 4]);
+ set_current_projection(proj[i + 4]);
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view;
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ for (U32 j = 0; j < 16; j++)
+ {
+ gGLLastModelView[j] = mShadowModelview[i + 4].m[j];
+ gGLLastProjection[j] = mShadowProjection[i + 4].m[j];
+ }
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ mShadowModelview[i + 4] = view[i + 4];
+ mShadowProjection[i + 4] = proj[i + 4];
- stop_glerror();
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- mShadow[i+4].bindTarget();
- mShadow[i+4].getViewport(gGLViewport);
- mShadow[i+4].clear();
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- U32 target_width = mShadow[i+4].getWidth();
+ stop_glerror();
+
+ //
+
+ mSpotShadow[i].bindTarget();
+ mSpotShadow[i].getViewport(gGLViewport);
+ mSpotShadow[i].clear();
+
+ U32 target_width = mSpotShadow[i].getWidth();
- static LLCullResult result[2];
+ static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
- RenderSpotLight = drawable;
+ RenderSpotLight = drawable;
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], FALSE, FALSE, target_width);
- RenderSpotLight = nullptr;
+ RenderSpotLight = nullptr;
- mShadow[i+4].flush();
- }
+ mSpotShadow[i].flush();
+ }
+ }
}
else
{ //no spotlight shadows
@@ -10849,6 +10775,7 @@ static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
{
LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
+ LL_PROFILE_GPU_ZONE("generateImpostor");
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -10919,22 +10846,47 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
{
markVisible(avatar->mDrawable, *viewer_camera);
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject* attached_object = attachment_iter->get())
- {
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
- }
- }
- }
+ if (preview_avatar)
+ {
+ // Only show rigged attachments for preview
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isRiggedMesh())
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ }
+ }
+ }
+ else
+ {
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ }
+ }
+ }
}
stateSort(*LLViewerCamera::getInstance(), result);
@@ -11092,8 +11044,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
- LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF );
- glDrawBuffersARB(1, &buff);
+ glDrawBuffers(1, &buff);
}
LLGLDisable blend(GL_BLEND);
@@ -11493,3 +11444,9 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
+void LLPipeline::overrideEnvironmentMap()
+{
+ //mReflectionMapManager.mProbes.clear();
+ //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin());
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 62d3ae7a39..59858cfcfc 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -38,6 +38,7 @@
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
+#include "llreflectionmapmanager.h"
#include <stack>
@@ -50,6 +51,7 @@ class LLVOAvatar;
class LLVOPartGroup;
class LLGLSLShader;
class LLDrawPoolAlpha;
+class LLSettingsSky;
typedef enum e_avatar_skinning_method
{
@@ -187,6 +189,7 @@ public:
LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -216,8 +219,9 @@ public:
U32 addObject(LLViewerObject *obj);
void enableShadows(const bool enable_shadows);
- void releaseShadowTargets();
- void releaseShadowTarget(U32 index);
+ void releaseSpotShadowTargets();
+ void releaseSunShadowTargets();
+ void releaseSunShadowTarget(U32 index);
// void setLocalLighting(const bool local_lighting);
// bool isLocalLightingEnabled() const;
@@ -286,19 +290,28 @@ public:
void renderGeom(LLCamera& camera, bool forceVBOUpdate = false);
- void renderGeomDeferred(LLCamera& camera);
- void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
+ void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+ void renderGeomPostDeferred(LLCamera& camera);
void renderGeomShadow(LLCamera& camera);
void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
- void renderDeferredLighting(LLRenderTarget* light_target);
+
+ // set env_mat parameter in given shader
+ void setEnvMat(LLGLSLShader& shader);
+
+ void bindReflectionProbes(LLGLSLShader& shader);
+ void unbindReflectionProbes(LLGLSLShader& shader);
+
+
+
+ void renderDeferredLighting();
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
- void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
- LLRenderTarget* getShadowTarget(U32 i);
+ LLRenderTarget* getSunShadowTarget(U32 i);
+ LLRenderTarget* getSpotShadowTarget(U32 i);
void generateHighlight(LLCamera& camera);
void renderHighlight(const LLViewerObject* obj, F32 fade);
@@ -426,6 +439,9 @@ public:
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
+ LLReflectionMapManager mReflectionMapManager;
+ void overrideEnvironmentMap();
+
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
@@ -460,6 +476,8 @@ public:
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
+ RENDER_TYPE_ALPHA_PRE_WATER = LLDrawPool::POOL_ALPHA_PRE_WATER,
+ RENDER_TYPE_ALPHA_POST_WATER = LLDrawPool::POOL_ALPHA_POST_WATER,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
@@ -517,6 +535,8 @@ public:
RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
+ RENDER_TYPE_PASS_PBR_OPAQUE = LLRenderPass::PASS_PBR_OPAQUE,
+ RENDER_TYPE_PASS_PBR_OPAQUE_RIGGED = LLRenderPass::PASS_PBR_OPAQUE_RIGGED,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -574,7 +594,8 @@ public:
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
- RENDER_DEBUG_IMPOSTORS = 0x100000000
+ RENDER_DEBUG_IMPOSTORS = 0x100000000,
+ RENDER_DEBUG_REFLECTION_PROBES = 0x200000000
};
public:
@@ -612,7 +633,6 @@ public:
static bool sUseTriStrips;
static bool sUseFarClip;
static bool sShadowRender;
- static bool sWaterReflections;
static bool sDynamicLOD;
static bool sPickAvatar;
static bool sReflectionRender;
@@ -626,26 +646,50 @@ public:
static bool sRenderAttachedLights;
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
+ static bool sReflectionProbesEnabled;
+ static bool sRenderPBR;
static S32 sVisibleLightCount;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
static LLTrace::EventStatHandle<S64> sStatBatchSize;
- //screen texture
- U32 mScreenWidth;
- U32 mScreenHeight;
-
- LLRenderTarget mScreen;
- LLRenderTarget mUIScreen;
- LLRenderTarget mDeferredScreen;
- LLRenderTarget mFXAABuffer;
- LLRenderTarget mEdgeMap;
- LLRenderTarget mDeferredDepth;
- LLRenderTarget mOcclusionDepth;
- LLRenderTarget mDeferredLight;
- LLRenderTarget mHighlight;
- LLRenderTarget mPhysicsDisplay;
+ class RenderTargetPack
+ {
+ public:
+ U32 width = 0;
+ U32 height = 0;
+
+ //screen texture
+ LLRenderTarget screen;
+ LLRenderTarget uiScreen;
+ LLRenderTarget deferredScreen;
+ LLRenderTarget fxaaBuffer;
+ LLRenderTarget edgeMap;
+ LLRenderTarget deferredDepth;
+ LLRenderTarget occlusionDepth;
+ LLRenderTarget deferredLight;
+
+ //sun shadow map
+ LLRenderTarget shadow[4];
+ LLRenderTarget shadowOcclusion[4];
+ };
+
+ // main full resoltuion render target
+ RenderTargetPack mMainRT;
+
+ // auxillary 512x512 render target pack
+ RenderTargetPack mAuxillaryRT;
+
+ // currently used render target pack
+ RenderTargetPack* mRT;
+
+ LLRenderTarget mSpotShadow[2];
+ LLRenderTarget mSpotShadowOcclusion[2];
+
+ LLRenderTarget mHighlight;
+ LLRenderTarget mPhysicsDisplay;
+ LLRenderTarget mPbrBrdfLut;
LLCullResult mSky;
LLCullResult mReflectedObjects;
@@ -657,15 +701,16 @@ public:
//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
LLPointer<LLVertexBuffer> mCubeVB;
- //sun shadow map
- LLRenderTarget mShadow[6];
- LLRenderTarget mShadowOcclusion[6];
+ //list of currently bound reflection maps
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
std::vector<LLVector3> mShadowFrustPoints[4];
LLVector4 mShadowError;
LLVector4 mShadowFOV;
LLVector3 mShadowFrustOrigin[4];
LLCamera mShadowCamera[8];
LLVector3 mShadowExtents[4][2];
+ // TODO : separate Sun Shadow and Spot Shadow matrices
glh::matrix4f mSunShadowMatrix[6];
glh::matrix4f mShadowModelview[6];
glh::matrix4f mShadowProjection[6];
@@ -845,21 +890,23 @@ protected:
// For quick-lookups into mPools (mapped by texture pointer)
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPoolAlpha* mAlphaPool;
- LLDrawPool* mSkyPool;
- LLDrawPool* mTerrainPool;
- LLDrawPool* mWaterPool;
- LLDrawPool* mGroundPool;
- LLRenderPass* mSimplePool;
- LLRenderPass* mGrassPool;
- LLRenderPass* mAlphaMaskPool;
- LLRenderPass* mFullbrightAlphaMaskPool;
- LLRenderPass* mFullbrightPool;
- LLDrawPool* mInvisiblePool;
- LLDrawPool* mGlowPool;
- LLDrawPool* mBumpPool;
- LLDrawPool* mMaterialsPool;
- LLDrawPool* mWLSkyPool;
+ LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr;
+ LLDrawPoolAlpha* mAlphaPoolPostWater = nullptr;
+ LLDrawPool* mSkyPool = nullptr;
+ LLDrawPool* mTerrainPool = nullptr;
+ LLDrawPool* mWaterPool = nullptr;
+ LLDrawPool* mGroundPool = nullptr;
+ LLRenderPass* mSimplePool = nullptr;
+ LLRenderPass* mGrassPool = nullptr;
+ LLRenderPass* mAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightPool = nullptr;
+ LLDrawPool* mInvisiblePool = nullptr;
+ LLDrawPool* mGlowPool = nullptr;
+ LLDrawPool* mBumpPool = nullptr;
+ LLDrawPool* mMaterialsPool = nullptr;
+ LLDrawPool* mWLSkyPool = nullptr;
+ LLDrawPool* mPBROpaquePool = nullptr;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
public:
@@ -966,7 +1013,6 @@ public:
static LLVector3 RenderShadowGaussian;
static F32 RenderShadowBlurDistFactor;
static bool RenderDeferredAtmospheric;
- static S32 RenderReflectionDetail;
static F32 RenderHighlightFadeTime;
static LLVector3 RenderShadowClipPlanes;
static LLVector3 RenderShadowOrthoClipPlanes;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7beb013fba..c3ce83e834 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -514,8 +514,8 @@
name="MapFrustumColor"
reference="White_10" />
<color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
+ name="MapParcelOutlineColor"
+ value="1 1 0 0.5" />
<color
name="MapTrackColor"
reference="Red" />
@@ -607,10 +607,10 @@
value="0 0 0 1" />
<color
name="NetMapGroupOwnAboveWater"
- reference="Purple" />
+ value="0.85 0 0.85 1" />
<color
name="NetMapGroupOwnBelowWater"
- value="0.78 0 0.78 1" />
+ value="0.63 0 0.63 1" />
<color
name="NetMapOtherOwnAboveWater"
value="0.24 0.24 0.24 1" />
@@ -619,10 +619,10 @@
value="0.12 0.12 0.12 1" />
<color
name="NetMapYouOwnAboveWater"
- value="0 1 1 1" />
+ value="0 0.85 0.85 1" />
<color
name="NetMapYouOwnBelowWater"
- value="0 0.78 0.78 1" />
+ value="0 0.63 0.63 1" />
<color
name="NotifyBoxColor"
value="LtGray" />
@@ -886,6 +886,22 @@
name="PanelNotificationListItem"
value="0.3 0.3 0.3 .3" />
+ <!-- profiles -->
+ <color
+ name="StatusUserOnline"
+ reference="White" />
+ <color
+ name="StatusUserOffline"
+ reference="LtGray_35" />
+ <!-- Groups visible in own profiles -->
+ <color
+ name="GroupVisibleInProfile"
+ reference="TextBgFocusColor" />
+ <color
+ name="GroupHiddenInProfile"
+ reference="Gray" />
+
+
<!-- Generic color names (legacy) -->
<color
name="white"
diff --git a/indra/newview/skins/default/textures/default_irradiance.png b/indra/newview/skins/default/textures/default_irradiance.png
new file mode 100644
index 0000000000..899e0ddf2a
--- /dev/null
+++ b/indra/newview/skins/default/textures/default_irradiance.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
new file mode 100644
index 0000000000..9a81c5f94b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
new file mode 100644
index 0000000000..88012cf8d1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
new file mode 100644
index 0000000000..ab02e7d42d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
new file mode 100644
index 0000000000..63b4bd2127
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
new file mode 100644
index 0000000000..4200182b0c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
new file mode 100644
index 0000000000..e12887f489
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/CopyBright.png b/indra/newview/skins/default/textures/icons/CopyBright.png
new file mode 100644
index 0000000000..8d21c47295
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/CopyBright.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Material.png b/indra/newview/skins/default/textures/icons/Inv_Material.png
new file mode 100644
index 0000000000..f5918ceaed
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Material.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
new file mode 100644
index 0000000000..aeba6b70f7
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
new file mode 100644
index 0000000000..d668fd8dfa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
new file mode 100644
index 0000000000..8f8caa10d8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
new file mode 100644
index 0000000000..42a209dda5
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
new file mode 100644
index 0000000000..644edf0ef6
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
new file mode 100644
index 0000000000..629c05ecb8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
new file mode 100644
index 0000000000..ecf66c0ee1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
new file mode 100644
index 0000000000..26123938fa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
deleted file mode 100644
index 3bb7f7183c..0000000000
--- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
new file mode 100644
index 0000000000..3a2ed399b2
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
new file mode 100644
index 0000000000..789f59a491
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
new file mode 100644
index 0000000000..4fb56c389c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
new file mode 100644
index 0000000000..ae04a256a4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_collapse_icon.png b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
new file mode 100644
index 0000000000..e4de49d4af
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_expand_icon.png b/indra/newview/skins/default/textures/map_ui_expand_icon.png
new file mode 100644
index 0000000000..08734b4cc0
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_expand_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a36b859b6c..5bf27bb64d 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -67,8 +67,6 @@ with the same filename but different name
<texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" />
<texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" />
- <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" />
-
<texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
<texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
@@ -191,6 +189,7 @@ with the same filename but different name
<texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
+ <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -303,6 +302,7 @@ with the same filename but different name
<texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" />
<texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" />
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
+ <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" />
<texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" />
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
@@ -447,6 +447,13 @@ with the same filename but different name
<texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
<texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" />
+ <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" />
+ <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" />
+
<texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" />
<texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" />
<texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" />
@@ -505,6 +512,19 @@ with the same filename but different name
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
+ <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/>
+ <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/>
+ <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/>
+
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
@@ -612,8 +632,7 @@ with the same filename but different name
<texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" />
<texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" />
- <texture name="first_login_image_left" file_name="windows/first_login_image_left.png" preload="true" />
- <texture name="first_login_image_right" file_name="windows/first_login_image_right.png" preload="true" />
+ <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" />
<texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" />
<texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" />
@@ -804,6 +823,8 @@ with the same filename but different name
<texture name="map_infohub.tga" />
<texture name="map_telehub.tga" />
<texture name="map_track_16.tga" />
+ <texture name="map_ui_collapse_icon.png" />
+ <texture name="map_ui_expand_icon.png" />
<texture name="notify_caution_icon.tga" />
diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg
new file mode 100644
index 0000000000..30f31341ed
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/first_login_image.jpg
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png
deleted file mode 100644
index 77904d7d12..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_left.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png
deleted file mode 100644
index 35ecce9c07..0000000000
--- a/indra/newview/skins/default/textures/windows/first_login_image_right.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml
deleted file mode 100644
index f98ced5f91..0000000000
--- a/indra/newview/skins/default/xui/da/panel_me.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Min profil" name="panel_me">
- <tab_container name="tabs">
- <panel label="MIN PROFIL" name="panel_profile"/>
- <panel label="MINE FAVORITTER" name="panel_picks"/>
- </tab_container>
-</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml
index 45946fd222..c8a3ad328e 100644
--- a/indra/newview/skins/default/xui/da/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml
@@ -7,8 +7,8 @@
ukendt
</text>
<text name="detail_texture_text">
- Terræn teksturer (kræver 512x512, 24 bit .tga filer)
- </text>
+ Terræn teksturer (kræver 1024x1024, 24 bit .tga filer)
+ </text>
<text name="height_text_lbl">
1 (Lav)
</text>
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml
deleted file mode 100644
index 66c3e69904..0000000000
--- a/indra/newview/skins/default/xui/da/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Åbn/luk sidebar" name="sidebar_openclose" tab_title="Åbn/luk sidebar"/>
- <sidetray_tab description="Hjem." name="sidebar_home" tab_title="Hjem">
- <panel label="hjem" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Redigér din profile og favoritter." name="sidebar_me" tab_title="Min profil">
- <panel_container name="panel_container">
- <panel label="Mig" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find venner, kontakter og personer tæt på." name="sidebar_people" tab_title="Personer">
- <panel_container name="panel_container">
- <panel label="Gruppe profil" name="panel_group_info_sidetray"/>
- <panel label="Blokerede beboere og objekter" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find steder du vil hen og steder du har været før." label="Steder" name="sidebar_places" tab_title="Steder">
- <panel label="Steder" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Browse din beholdning." name="sidebar_inventory" tab_title="Min beholdning">
- <panel label="Redigér beholdning" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Ændre dit nuværende udseende" name="sidebar_appearance" tab_title="Mit udseende">
- <panel label="Redigér udseende" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 814305c1bc..e4f99d14e9 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -106,7 +106,7 @@
<string name="LoginFailedNoNetwork">
Netværksfejl: Kunne ikke etablere forbindelse, check venligst din netværksforbindelse.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Login fejlede.
</string>
<string name="Quit">
@@ -443,9 +443,6 @@ Prøv venligst om lidt igen.
<string name="GroupNameNone">
(ingen)
</string>
- <string name="AvalineCaller">
- Avaline opkalder [ORDER]
- </string>
<string name="AssetErrorNone">
Ingen fejl
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
index eacd11c3e6..b386d0288c 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
In Inventar kopieren
</floater.string>
- <text name="desc txt">
- Beschreibung:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Vorschau Seitenverhältnis
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen">
- <combo_item name="Unconstrained">
- keines
- </combo_item>
- <combo_item name="1:1" tool_tip="Gruppeninsignien oder Beschreibung">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE]-Profil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Anzeigen und Suchergebnisse, Landmarken">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Über Land">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profilauswahl">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Verwerfen" name="Discard"/>
- <button label="Speichern unter" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Beschreibung:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Vorschau Seitenverhältnis
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Verwerfen" name="Discard"/>
+ <button label="Speichern unter" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_profile.xml b/indra/newview/skins/default/xui/de/floater_profile.xml
new file mode 100644
index 0000000000..eb03463930
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessen" name="panel_profile_interests"/>
+ <panel label="Auswahlen" name="panel_profile_picks"/>
+ <panel label="Anzeige" name="panel_profile_classifieds"/>
+ <panel label="Echtes Leben" name="panel_profile_firstlife"/>
+ <panel label="Hinweise" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Profiländerungen speichern und schließen"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index f0152ad8cd..636f320a95 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-Mail senden
</string>
+ <string name="facebook_progress_str">
+ Auf Facebook posten
+ </string>
<string name="profile_progress_str">
Posten
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Speichern auf Computer
</string>
+ <string name="facebook_succeeded_str">
+ Bild hochgeladen
+ </string>
<string name="profile_succeeded_str">
Bild hochgeladen
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Auf Computer gespeichert!
</string>
+ <string name="facebook_failed_str">
+ Fehler beim Hochladen des Bilds in Ihre Facebook-Chronik.
+ </string>
<string name="profile_failed_str">
Fehler beim Hochladen des Bilds in Ihr Profil.
</string>
diff --git a/indra/newview/skins/default/xui/de/menu_name_field.xml b/indra/newview/skins/default/xui/de/menu_name_field.xml
new file mode 100644
index 0000000000..1d293c9361
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Anzeigenamen kopieren" name="copy_display"/>
+ <menu_item_call label="Agent-Namen kopieren" name="copy_name"/>
+ <menu_item_call label="Agent-ID kopieren" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 359a835630..a72784f70b 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2698,6 +2698,9 @@ Wählen Sie eine kleinere Landfläche.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
index bd270697ea..8adacb4a5f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Abbrechen" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
index f6a8fda23e..1a0bbc7d30 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die gleichzeitig Einwohner von Second Life sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
- <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, gehen Sie zur Registerkarte „Status“."/>
+ <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die ebenfalls Second Life-Einwohner sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
+ <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, wechseln Sie zur Registerkarte &quot;Status&quot;."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL-Freunde"/>
<accordion_tab name="tab_suggested_friends" title="Diese Personen als SL-Freunde hinzufügen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
index bc48931129..fac9fe9984 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
@@ -2,10 +2,10 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Bildauflösung">
<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <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="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Bildfilter">
<combo_box.item label="Kein Filter" name="NoFilter"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_status.xml b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
index 23c9d3b75f..1fefef548e 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
@@ -13,7 +13,7 @@
</text>
</panel>
<text name="status_caption_label">
- Was machst du gerade?
+ Was machen Sie gerade?
</text>
<button label="Posten" name="post_status_btn"/>
<button label="Abbrechen" name="cancel_status_btn"/>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index 9fec5a242d..e50124c37e 100644
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
@@ -46,7 +46,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
<check_box label="Jeder kann beitreten" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
<check_box label="Kosten für Beitritt" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Wenn Beitrittsgebühr aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
- <combo_box name="group_mature_check" tool_tip="Inhaltseinstufungen kennzeichnen die in einer Gruppe zulässigen Inhalte und Verhaltensweisen">
+ <combo_box name="group_mature_check" tool_tip="Legt fest, ob Ihre Gruppe als moderat eingestufte Informationen enthält">
<combo_item name="select_mature">
- Inhaltseinstufung auswählen -
</combo_item>
diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fc911a64df
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Unbekannt"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
+ <button name="profile_btn" tool_tip="Profil anzeigen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
deleted file mode 100644
index f49446fbbf..0000000000
--- a/indra/newview/skins/default/xui/de/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mein Profil" name="panel_me">
- <panel label="MEINE AUSWAHLEN" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 81de679429..e4a4c1033e 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -40,6 +40,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Alle"/>
+ <accordion_tab name="tab_suggested_friends" title="Potenzielle Freunde"/>
</accordion>
</panel>
<panel label="GRUPPEN" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classified.xml b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
new file mode 100644
index 0000000000..5c11a01977
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderat
+ </panel.string>
+ <panel.string name="type_pg">
+ Generelle Inhalte
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] Teleportieren, [MAP] Karten, [PROFILE] Profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Aktiviert
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Deaktiviert
+ </panel.string>
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <string name="publish_label">
+ Veröffentlichen
+ </string>
+ <string name="save_label">
+ Speichern
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Standort:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Erstellungsdatum:"/>
+ <text_editor name="creation_date" tool_tip="Erstellungsdatum" value="[date]"/>
+ <text name="price_for_listing_label" value="Preis für Auflistung:"/>
+ <text_editor name="price_for_listing" tool_tip="Preis für Auflistung.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Klicks:"/>
+ <text_editor name="click_through_text" tool_tip="Click-Through-Daten" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Autom. erneuern:"/>
+ <text name="auto_renew" value="Aktiviert"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Beschreibung:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titel:
+ </text>
+ <text name="description_label">
+ Beschreibung:
+ </text>
+ <text name="location_label">
+ Standort:
+ </text>
+ <text name="classified_location_edit">
+ Laden...
+ </text>
+ <button label="Aktuellen Standort verwenden" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <icons_combo_box label="Generelle Inhalte" name="content_type_edit">
+ <icons_combo_box.item label="Moderate Inhalte" name="mature_ci" value="Adult"/>
+ <icons_combo_box.item label="Generelle Inhalte" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Jede Woche automatisch erneuern" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preis für Auflistung:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preis für Auflistung." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleportieren" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Karte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Bearbeiten" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Abbrechen" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..83549cb138
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anzeige" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Keine Anzeigen"/>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
index 2521920e83..0f65090209 100644
--- a/indra/newview/skins/default/xui/de/floater_picks.xml
+++ b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Auswahlen"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_interests.xml b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
new file mode 100644
index 0000000000..0f36f76aa0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessen" name="panel_profile_interests">
+ <text name="I Want To:">
+ Ich möchte:
+ </text>
+ <check_box label="Erstellen" name="chk0"/>
+ <check_box label="Erkunden" name="chk1"/>
+ <check_box label="Treffen" name="chk2"/>
+ <check_box label="Angestellt werden" name="chk6"/>
+ <check_box label="Gruppe" name="chk3"/>
+ <check_box label="Kaufen" name="chk4"/>
+ <check_box label="Verkaufen" name="chk5"/>
+ <check_box label="Anstellen" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Skills:">
+ Fähigkeiten:
+ </text>
+ <check_box label="Texturen" name="schk0"/>
+ <check_box label="Architektur" name="schk1"/>
+ <check_box label="Modellierung" name="schk3"/>
+ <check_box label="Eventplanung" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Benutzerdefinierte Charaktere" name="schk5"/>
+ <line_editor name="skills_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Languages:">
+ Sprachen:
+ </text>
+ <line_editor name="languages_edit">
+ (wird geladen...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_notes.xml b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
new file mode 100644
index 0000000000..05c46ff858
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anmerkungen &amp; Privatsphäre" name="panel_notes">
+ <text name="status_message" value="Private Anmerkungen zu diesem Avatar:"/>
+ <text name="status_message2" value="Dieser Avatar darf:"/>
+ <check_box label="Sehen, wenn ich online bin" name="status_check"/>
+ <check_box label="Mich auf der Weltkarte sehen" name="map_check"/>
+ <check_box label="Meine Objekte bearbeiten, löschen oder nehmen" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_pick.xml b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
new file mode 100644
index 0000000000..1f44ba8b1b
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <line_editor name="pick_location">
+ Laden...
+ </line_editor>
+ <button label="Teleportieren" name="teleport_btn"/>
+ <button label="Auf Karte anzeigen" name="show_on_map_btn"/>
+ <button label="Standort festlegen" name="set_to_curr_location_btn" tool_tip="Aktuellen Standort verwenden"/>
+ <button label="Auswahl speichern" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
new file mode 100644
index 0000000000..96403715e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Auswahlen" name="panel_picks">
+ <string name="no_picks" value="Keine Auswahl"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Erzählen Sie von Ihren Lieblingsorten in Second Life.
+ </text>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..baaa58e1d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Zurzeit online
+ </string>
+ <string name="status_offline">
+ Zurzeit offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=de
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=de
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Keine"/>
+ <string name="no_group_text" value="Keine"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Entwickler"/>
+ <string name="FSSupp" value="Support"/>
+ <string name="FSQualityAssurance" value="Fehlersuche"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Name:"/>
+ <button label="Name:" name="set_name" tool_tip="Anzeigenamen festlegen"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(wird geladen...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status unbekannt"/>
+ <text name="label" value="Second Life-Geburtsdatum:"/>
+ <text name="label2" value="Konto:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppen:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="In Gruppe einladen"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Info:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Objekt geben:"/>
+ <text name="Give inventory" tool_tip="Legen Sie hier Inventarobjekte ab, um Sie dieser Person zu geben.">
+ Inventarobjekt hier ablegen.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Auf Karte anzeigen" label_selected="Auf Karte anzeigen" name="show_on_map_btn" tool_tip="Einwohner auf Karte lokalisieren"/>
+ <button label="Bezahlen" label_selected="Bezahlen" name="pay" tool_tip="Geld an den Einwohner zahlen"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teleportation anbieten" label_selected="Teleportation anbieten" name="teleport" tool_tip="Dem Einwohner eine Teleportation anbieten"/>
+ <button label="Instant Message" label_selected="Instant Message" name="im" tool_tip="Instant Message-Sitzung öffnen"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Freund hinzufügen" label_selected="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/>
+ <button label="Blockieren" name="block" tool_tip="Diesen Einwohner blockieren"/>
+ <button label="Blockierung aufheben" name="unblock" tool_tip="Diesen Einwohner nicht mehr blockieren"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="In Suche anzeigen" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_web.xml b/indra/newview/skins/default/xui/de/panel_profile_web.xml
new file mode 100644
index 0000000000..a03918f4b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Ladezeit: [TIME] Sekunden"/>
+ <line_editor name="url_edit">
+ (wird geladen..)
+ </line_editor>
+ <flyout_button label="Laden" name="load" tool_tip="Lädt diese Profilseite im integrierten Webbrowser.">
+ <flyout_button.item label="Im Viewer-Browser öffnen" name="open_item"/>
+ <flyout_button.item label="In externem Browser öffnen" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Webprofil ausklappen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 7801be30e4..42ba5b5269 100644
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>
<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512)
- </text>
+ Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024)
+ </text>
<text name="height_text_lbl">
1 (niedrig)
</text>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index ba26f721fe..0120f7e5bd 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -186,7 +186,7 @@ Voice-Server-Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Anmeldung fehlgeschlagen
</string>
<string name="Quit">
@@ -356,6 +356,24 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="TestingDisconnect">
Verbindungsabbruch wird getestet
</string>
+ <string name="SocialFacebookConnecting">
+ Mit Facebook verbinden...
+ </string>
+ <string name="SocialFacebookPosting">
+ Posten...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook-Verbindung trennen...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problem beim Verbinden mit Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problem beim Posten auf Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problem beim Trennen der Facebook-Verbindung
+ </string>
<string name="SocialFlickrConnecting">
Verbinden mit Flickr...
</string>
@@ -673,9 +691,6 @@ nächsten Eigentümer angehängt werden.
<string name="GroupNameNone">
(keiner)
</string>
- <string name="AvalineCaller">
- Avaline-Anfrufer [ORDER]
- </string>
<string name="AssetErrorNone">
Kein Fehler
</string>
@@ -2578,9 +2593,21 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="NoPicksClassifiedsText">
Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus&quot;-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.
</string>
+ <string name="NoPicksText">
+ Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Auswahl zu erstellen.
+ </string>
+ <string name="NoClassifiedsText">
+ Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Anzeige zu erstellen.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Der Einwohner hat keine Auswahl oder Anzeigen
</string>
+ <string name="NoAvatarPicksText">
+ Der Einwohner hat keine Auswahl
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Der Einwohner hat keine Anzeigen
+ </string>
<string name="PicksClassifiedsLoadingText">
Wird geladen...
</string>
@@ -4558,6 +4585,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="share_alert">
Objekte aus dem Inventar hier her ziehen
</string>
+ <string name="facebook_post_success">
+ Sie haben auf Facebook gepostet.
+ </string>
<string name="flickr_post_success">
Sie haben auf Flickr gepostet.
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index b2d9e53039..4678d65b85 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -164,6 +164,7 @@
left_pad="2"
name="Description"
spellcheck="true"
+ parse_urls="true"
top_delta="0"
width="365"
word_wrap="true" />
@@ -1892,7 +1893,29 @@ Only large parcels can be listed in search.
left="110"
name="parcel_enable_voice_channel_local"
width="300" />
- </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="media"
+ top_pad="10"
+ width="100">
+ Media:
+ </text>
+ <check_box
+ height="16"
+ label="Obscure MOAP"
+ layout="topleft"
+ left="110"
+ left_pad="0"
+ name="obscure_moap"
+ tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa."
+ width="300" />
+ </panel>
<panel
border="true"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index 38428b36fc..7278e55d57 100644
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -46,14 +46,14 @@
name="GridSubUnit"
top_pad="0"
width="200" />
- <check_box
+ <!-- <check_box
control_name="GridCrossSections"
height="16"
label="View cross-sections"
layout="topleft"
name="GridCrossSection"
top_pad="5"
- width="200" />
+ width="200" />-->
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml
index 984894b016..5b14c827d0 100644
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_classified.xml
@@ -2,20 +2,19 @@
<floater
positioning="cascading"
can_close="true"
- can_resize="true"
+ can_resize="false"
height="572"
help_topic="sidebar_me"
min_width="333"
min_height="440"
- name="floater_picks"
+ name="floater_classified"
save_rect="true"
- save_visibility="true"
- reuse_instance="true"
- title="Picks"
+ save_visibility="false"
+ title="Classified"
width="333" >
<panel
- class="panel_me"
+ class="panel_classified_info"
name="main_panel"
- filename="panel_me.xml"
+ filename="panel_classified_info.xml"
follows="all"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
new file mode 100644
index 0000000000..63eaffde18
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+ legacy_header_height="18"
+ height="130"
+ min_height="130"
+ width="270"
+ min_width="270"
+ layout="topleft"
+ name="floater_combo"
+ title="floater_combo"
+ help_topic="floater_combo"
+ can_resize="false"
+ can_minimize="false">
+ <text
+ follows="top|left|right"
+ height="10"
+ layout="topleft"
+ left="20"
+ name="combo_text"
+ top="30"
+ width="200">
+ Select an option:
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="20"
+ name="combo_options"
+ top_delta="20"
+ width="230"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="OK"
+ layout="topleft"
+ top_delta="40"
+ left="20"
+ name="combo_ok"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ left_pad="50"
+ name="combo_cancel"
+ width="90"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index bba30626b2..632daaec7e 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -88,6 +88,7 @@
spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
+ commit_on_focus_lost="true"
top_pad="5"
width="290"
wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 9a9fd32a77..3c8f415860 100644
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
@@ -23,7 +23,7 @@
use_ellipses="true"
width="380"
wrap="true">
- The name you give your avatar is called your Display Name. You can change it once a week.
+ Your display name is what other people see above your head. It is different from your login name. You can change it once a week.
</text>
<text
type="string"
@@ -85,19 +85,10 @@
width="120" />
<button
height="23"
- label="Reset"
- layout="topleft"
- font="SansSerif"
- left_pad="5"
- name="reset_btn"
- tool_tip="Make Display Name the same as Username"
- width="120" />
- <button
- height="23"
label="Cancel"
font="SansSerif"
layout="topleft"
- left_pad="5"
+ left_pad="125"
name="cancel_btn"
width="120" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index d783d1e23c..e91efb89b2 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="466"
+ height="486"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -95,12 +95,29 @@
width="126" />
<icon
height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_material"
+ top="122"
+ width="16" />
+ <check_box
+ height="16"
+ label="Materials"
+ layout="topleft"
+ left_pad="2"
+ name="check_material"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
image_name="Inv_Notecard"
layout="topleft"
left="8"
mouse_opaque="true"
name="icon_notecard"
- top="122"
+ top="142"
width="16" />
<check_box
height="16"
@@ -117,7 +134,7 @@
left="8"
mouse_opaque="true"
name="icon_object"
- top="142"
+ top="162"
width="16" />
<check_box
height="16"
@@ -134,7 +151,7 @@
left="8"
mouse_opaque="true"
name="icon_script"
- top="162"
+ top="182"
width="16" />
<check_box
height="16"
@@ -151,7 +168,7 @@
left="8"
mouse_opaque="true"
name="icon_sound"
- top="182"
+ top="202"
width="16" />
<check_box
height="16"
@@ -168,7 +185,7 @@
left="8"
mouse_opaque="true"
name="icon_texture"
- top="202"
+ top="222"
width="16" />
<check_box
height="16"
@@ -185,7 +202,7 @@
left="8"
mouse_opaque="true"
name="icon_snapshot"
- top="222"
+ top="242"
width="16" />
<check_box
height="16"
@@ -202,7 +219,7 @@
left="8"
mouse_opaque="true"
name="icon_settings"
- top="242"
+ top="262"
width="16" />
<check_box
height="16"
@@ -220,7 +237,7 @@
layout="topleft"
left="8"
name="All"
- top="262"
+ top="282"
width="100" />
<button
height="20"
@@ -274,7 +291,7 @@
width="260"/>
<check_box
height="16"
- top="352"
+ top="372"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -290,7 +307,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="370"
+ top="390"
width="144">
- OR -
</text>
@@ -298,7 +315,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="388"
+ top="408"
left="8"
width="270">
<radio_item
@@ -368,6 +385,6 @@
layout="topleft"
name="Close"
right="-6"
- top="434"
+ top="454"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..9639e70544 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -16,11 +16,35 @@
width="200">
<floater.string
name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG]
+ </floater.string>
+ <floater.string
+ name="ParcelNameMsg">
+ [PARCEL_NAME]
+ </floater.string>
+ <floater.string
+ name="ParcelSalePriceMsg">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ </floater.string>
+ <floater.string
+ name="ParcelSaleAreaMsg">
+ Area: [AREA]m²
+ </floater.string>
+ <floater.string
+ name="ParcelOwnerMsg">
+ Owner: [PARCEL_OWNER]
+ </floater.string>
+ <floater.string
+ name="RegionNameMsg">
+ Region: [REGION_NAME]
</floater.string>
<floater.string
- name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ name="ToolTipHintMsg">
+ Double-click to open map
+ </floater.string>
+ <floater.string
+ name="AltToolTipHintMsg">
+ Double-click to teleport
</floater.string>
<floater.string name="mini_map_caption">
Mini-map
@@ -37,105 +61,73 @@
<text
type="string"
length="1"
- bottom="218"
label="N"
layout="topleft"
- left="0"
name="floater_map_north"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
N
</text>
<text
type="string"
length="1"
- bottom="218"
label="E"
layout="topleft"
- left="0"
name="floater_map_east"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
E
</text>
<text
type="string"
length="1"
- bottom="205"
label="W"
layout="topleft"
- left="0"
name="floater_map_west"
- right="11"
- text_color="1 1 1 0.7"
- top="175">
+ text_color="1 1 1 0.7">
W
</text>
<text
type="string"
length="1"
- bottom="218"
label="S"
layout="topleft"
- left="0"
name="floater_map_south"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
S
</text>
<text
type="string"
length="1"
- bottom="218"
label="SE"
layout="topleft"
- left="0"
name="floater_map_southeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SE
</text>
<text
type="string"
length="1"
- bottom="218"
label="NE"
layout="topleft"
- left="0"
name="floater_map_northeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NE
</text>
<text
type="string"
length="1"
- bottom="218"
label="SW"
layout="topleft"
- left="0"
name="floater_map_southwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SW
</text>
<text
type="string"
length="1"
- bottom="218"
label="NW"
layout="topleft"
- left="0"
name="floater_map_northwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NW
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml
new file mode 100644
index 0000000000..434123faf0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml
@@ -0,0 +1,532 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ height="887"
+ width="256"
+ min_height="500"
+ min_width="256"
+ layout="topleft"
+ name="material editor"
+ help_topic="material_editor"
+ title="[MATERIAL_NAME]">
+ <string name="no_upload_fee_string">no upload fee</string>
+ <string name="upload_fee_string">L$[FEE] upload fee</string>
+ <string name="material_selection_title">Material selection</string>
+ <string name="material_selection_text">Select material:</string>
+ <string name="material_override_title">Material override</string>
+
+ <scroll_container
+ name="materials_scroll"
+ top="14"
+ left="4"
+ height="768"
+ width="247"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ border="false"
+ name="scroll_panel"
+ top="0"
+ left="0"
+ height="768"
+ width="247"
+ >
+ <check_box
+ follows="left|top"
+ label="Double Sided"
+ left="10"
+ top="0"
+ name="double sided"
+ height="25"
+ width="120" />
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="196"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="base_color_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="128">
+ Base Color:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="base_color_texture"
+ tool_tip="Base Color map. Alpha channel is optional and used for transparency."
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="base_color_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="base color"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Transparency
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="transparency"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label alphamode"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="5"
+ width="90">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="alpha mode"
+ top_pad="4"
+ width="96">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="OPAQUE" />
+ <combo_box.item
+ label="Alpha blending"
+ name="Alpha blending"
+ value="BLEND" />
+ <combo_box.item
+ label="Alpha masking"
+ name="Alpha masking"
+ value="MASK" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Alpha Cutoff
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="alpha cutoff"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="metallic_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ >
+ Metallic-Roughness:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ width="128"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="metallic_roughness_texture"
+ tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness."
+ top_pad="8"
+ />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="metallic_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Metallic Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="metalness factor"
+ width="64"
+ />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ >
+ Roughness Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="roughness factor"
+ width="64"
+ />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="emissive_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Emissive:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="emissive_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="emissive_upload_fee"
+ >
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ >
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="emissive color"
+ width="40" />
+ <!--<text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="64"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ >
+ Intensity
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ max_val="100"
+ width="64"
+ />-->
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ top_pad="5"
+ name="normal_texture_pnl"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64">
+ Normal:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="normal_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="normal_upload_fee"
+ >
+ No upload fee
+ </text>
+ </panel>
+ </panel>
+ </scroll_container>
+
+ <panel
+ follows="right|bottom"
+ width="246"
+ height="97"
+ layout="bottomright"
+ top_pad="0"
+ left="5"
+ name="button_panel"
+ >
+ <text
+ type="string"
+ name="unsaved_changes"
+ font.style="BOLD"
+ text_color="DrYellow"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="200"
+ layout="topleft"
+ left="10"
+ top="0"
+ >
+ Usaved changes
+ </text>
+ <button
+ follows="left|top"
+ height="25"
+ label="Save"
+ layout="topleft"
+ name="save"
+ top_pad="7"
+ left="0"
+ width="120" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Save As..."
+ layout="topleft"
+ name="save_as"
+ top_delta="0"
+ left_pad="6"
+ width="120" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="220"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ name="total_upload_fee"
+ >
+ Total upload fee: L$ [FEE]
+ </text>
+
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="button_border"
+ top_pad="7"
+ width="246"/>
+
+ <button
+ follows="left|top"
+ height="25"
+ label="Cancel"
+ layout="topleft"
+ name="cancel"
+ top_pad="7"
+ left="61"
+ width="121" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e499ddbc2f..21c894d3af 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -830,6 +830,7 @@
<combo_item name="physics_medium"> Medium </combo_item>
<combo_item name="physics_low"> Low </combo_item>
<combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="physics_bounding_box"> Bounding Box </combo_item>
<combo_item name="load_from_file"> From file </combo_item>
</combo_box>
<line_editor
diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml
index 6aff387dcb..db81c8bba2 100644
--- a/indra/newview/skins/default/xui/en/floater_my_environments.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml
@@ -119,7 +119,7 @@
follows="all"
layout="topleft"
name="pnl_settings"
- filter_asset_type="settings"/>
+ filter_asset_types="settings"/>
</panel>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/en/floater_perms_default.xml b/indra/newview/skins/default/xui/en/floater_perms_default.xml
index 49dc719a24..9ca61671e1 100644
--- a/indra/newview/skins/default/xui/en/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="250"
+ height="266"
layout="topleft"
name="perms default"
help_topic="perms_default"
@@ -10,7 +10,7 @@
width="700">
<panel
follows="left|top|right|bottom"
- height="200"
+ height="216"
label="Default Permissions"
layout="topleft"
left="10"
@@ -549,6 +549,70 @@
left_pad="0"
top_delta="0"
width="100" />
+ <text
+ name="label_14"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when GLTF Materials are created"
+ width="100">
+ Materials
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="MaterialsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="env_material_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Materials" />
+ </check_box>
+ <check_box
+ control_name="MaterialsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="env_materials_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="MaterialsNextOwnerCopy"
+ control_name="MaterialsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="env_materials_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="MaterialsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="env_materials_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="MaterialsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="env_materials_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
</panel>
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 0a4acd979a..4a08cc5285 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -272,51 +272,6 @@
Hardware
</text>
- <slider
- control_name="RenderFogRatio"
- follows="left|top"
- height="16"
- initial_value="4"
- decimal_digits="1"
- label="Fog Distance Ratio:"
- label_width="185"
- layout="topleft"
- left="30"
- name="fog"
- min_val="0.5"
- max_val="10"
- increment="0.1"
- top_delta="16"
- width="332" />
-
- <slider
- control_name="RenderGamma"
- follows="left|top"
- height="16"
- initial_value="1"
- decimal_digits="2"
- label="Gamma:"
- label_width="185"
- layout="topleft"
- left="30"
- name="gamma"
- min_val="0"
- max_val="2"
- increment="0.01"
- top_delta="16"
- width="332" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="30"
- name="(brightness, lower is brighter)"
- top_delta="16"
- width="260">
- (0 = default brightness, lower = brighter)
- </text>
<check_box
control_name="RenderAnisotropic"
@@ -585,20 +540,6 @@
</check_box>
<check_box
- control_name="RenderObjectBump"
- height="16"
- initial_value="true"
- label="Bump mapping and shiny"
- layout="topleft"
- left="420"
- name="BumpShiny"
- top_delta="16"
- width="300">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderLocalLights"
height="16"
initial_value="true"
@@ -610,116 +551,6 @@
width="300" />
<slider
- control_name="RenderTerrainDetail"
- follows="left|top"
- height="16"
- label="Terrain Detail:"
- label_width="165"
- layout="topleft"
- left="440"
- show_text="false"
- initial_value="0"
- increment="1"
- min_val="0"
- max_val="1"
- name="TerrainDetail"
- top_delta="16"
- width="280" >
- <slider.commit_callback
- function="Pref.UpdateSliderText"
- parameter="TerrainDetail" />
- </slider>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- top_delta="0"
- left_delta="284"
- name="TerrainDetailText"
- text_readonly_color="LabelDisabledColor"
- width="65">
- Low
- </text>
-
- <check_box
- control_name="RenderAvatarCloth"
- height="16"
- initial_value="true"
- label="Avatar cloth"
- layout="topleft"
- left="440"
- name="AvatarCloth"
- top_delta="16"
- width="280" />
-
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- name="ReflectionsText"
- text_readonly_color="LabelDisabledColor"
- top_delta="16"
- left="440"
- width="128">
- Water Reflections:
- </text>
- <combo_box
- control_name="RenderReflectionDetail"
- height="18"
- layout="topleft"
- left_delta="170"
- top_delta="0"
- name="Reflections"
- width="150">
- <combo_box.item
- label="None; opaque"
- name="0"
- value="-2"/>
- <combo_box.item
- label="None; transparent"
- name="0"
- value="-1"/>
- <combo_box.item
- label="Minimal"
- name="0"
- value="0"/>
- <combo_box.item
- label="Terrain and trees"
- name="1"
- value="1"/>
- <combo_box.item
- label="All static objects"
- name="2"
- value="2"/>
- <combo_box.item
- label="All avatars and objects"
- name="3"
- value="3"/>
- <combo_box.item
- label="Everything"
- name="4"
- value="4"/>
- </combo_box>
-
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="440"
- name="WindLightUseAtmosShaders"
- top_delta="16"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <slider
control_name="WLSkyDetail"
decimal_digits="0"
follows="left|top"
@@ -729,7 +560,7 @@
label="Sky:"
label_width="145"
layout="topleft"
- left="460"
+ left="420"
min_val="16"
max_val="128"
name="SkyMeshDetail"
@@ -755,26 +586,12 @@
</text>
<check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="460"
- name="UseLightShaders"
- top_delta="16"
- width="260">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderDeferredSSAO"
height="16"
initial_value="true"
label="Ambient Occlusion"
layout="topleft"
- left="480"
+ left="420"
name="UseSSAO"
top_delta="16"
width="240">
@@ -788,7 +605,7 @@
initial_value="true"
label="Depth of Field"
layout="topleft"
- left="480"
+ left="420"
name="UseDoF"
top_delta="16"
width="240">
@@ -796,29 +613,13 @@
function="Pref.RenderOptionUpdate" />
</check_box>
- <!--
- <check_box
- control_name="RenderUseAdvancedAtmospherics"
- height="16"
- initial_value="true"
- label="Advanced Atmospherics"
- layout="topleft"
- left="480"
- name="UseAdvancedAtmo"
- top_delta="16"
- width="240">
- <check_box.commit_callback
- function="Pref.AdvancedAtmosphericsEnable" />
- </check_box>
- -->
-
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
- left="480"
+ left="420"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
top_delta="16"
@@ -846,15 +647,53 @@
name="2"
value="2"/>
</combo_box>
-
-<!-- End of Advanced Settings block -->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="RenderReflectionDetailText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="16"
+ width="128">
+ Reflections:
+ </text>
+ <combo_box
+ control_name="RenderReflectionProbeDetail"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="ReflectionDetial"
+ width="150">
+ <combo_box.item
+ label="Disabled"
+ name="0"
+ value="-1"/>
+ <combo_box.item
+ label="Static Only"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Static+Dynamic"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Realtime"
+ name="2"
+ value="2"/>
+ </combo_box>
+
+ <!-- End of Advanced Settings block -->
<view_border
bevel_style="in"
height="0"
layout="topleft"
left="13"
name="horiz_border"
- top_pad="21"
+ top="338"
top_delta="5"
width="774"/>
<button
@@ -864,7 +703,7 @@
layout="topleft"
left="20"
name="Defaults"
- top_delta="10"
+ top_delta="20"
width="210">
<button.commit_callback
function="Pref.HardwareDefaults" />
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index e1e7e1c8c8..048cf7df62 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -17,94 +17,122 @@
name="Copy">
Copy To Inventory
</floater.string>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="19"
- layout="topleft"
- left="10"
- name="desc txt"
- top="21"
- width="90">
- Description:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- font="SansSerif"
- height="19"
- layout="topleft"
- left_pad="0"
- max_length_bytes="127"
- name="desc"
- width="190" />
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left="110"
- name="dimensions"
- top="255"
- width="200">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left_delta="-110"
- name="aspect_ratio"
- top_pad="5"
- width="200">
- Preview aspect ratio
- </text>
- <combo_box
- allow_text_entry="true"
- top_delta="-3"
- follows="right|bottom"
- height="23"
- left_pad="10"
- max_chars="20"
- mouse_opaque="true"
- enabled="true"
- width="108"
- name="combo_aspect_ratio"
- tool_tip="Preview at a fixed aspect ratio">
- </combo_box>
- <button
- follows="right|bottom"
- height="22"
- label="OK"
- layout="topleft"
- left="6"
- name="Keep"
- top_pad="5"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Discard"
- layout="topleft"
- left_pad="5"
- name="Discard"
- top_delta="0"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Save As"
- layout="topleft"
- left_pad="5"
- name="save_tex_btn"
- top_delta="0"
- width="110" />
+ <layout_stack
+ animate="false"
+ name="preview_stack"
+ top_pad="15"
+ left="0"
+ follows="all"
+ orientation="vertical"
+ height="350"
+ width="370"
+ layout="topleft">
+ <layout_panel
+ name="texture_panel"
+ height="305"
+ top_pad="0"
+ left="0"
+ follows="left|top"
+ layout="topleft">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="6"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length_bytes="127"
+ name="desc"
+ width="190" />
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="dimensions"
+ bottom="-40"
+ width="200">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="-110"
+ name="aspect_ratio"
+ top_pad="5"
+ width="200">
+ Preview aspect ratio
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ top_delta="-3"
+ follows="right|bottom"
+ height="23"
+ left_pad="10"
+ max_chars="20"
+ mouse_opaque="true"
+ enabled="true"
+ width="108"
+ name="combo_aspect_ratio"
+ tool_tip="Preview at a fixed aspect ratio">
+ </combo_box>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="45"
+ bottom="-40"
+ left="0"
+ follows="right|bottom"
+ auto_resize="false"
+ layout="topleft">
+ <button
+ follows="right|bottom"
+ height="22"
+ label="OK"
+ layout="topleft"
+ left="6"
+ name="Keep"
+ top_pad="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Discard"
+ layout="topleft"
+ left_pad="5"
+ name="Discard"
+ top_delta="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Save As"
+ layout="topleft"
+ left_pad="5"
+ name="save_tex_btn"
+ top_delta="0"
+ width="110" />
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml
new file mode 100644
index 0000000000..32ab811a6e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ name="avatarinfo"
+ height="510"
+ width="510"
+ layout="topleft"
+ can_close="true"
+ can_resize="true"
+ help_topic="panel_my_profile_tab"
+ min_height="510"
+ min_width="510"
+ positioning="centered"
+ save_rect="true"
+ title="Profile"
+>
+ <panel
+ name="panel_profile_view"
+ top="0"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ class="panel_profile"
+ >
+ <tab_container
+ name="panel_profile_tabs"
+ top_pad="5"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ layout="topleft"
+ halign="center"
+ tab_min_width="81"
+ tab_height="30"
+ tab_position="top"
+ >
+ <panel
+ name="panel_profile_secondlife"
+ label="BIO"
+ layout="topleft"
+ class="panel_profile_secondlife"
+ filename="panel_profile_secondlife.xml"
+ help_topic="profile_secondlife_tab"
+ />
+ <panel
+ name="panel_profile_web"
+ label="FEED"
+ layout="topleft"
+ class="panel_profile_web"
+ filename="panel_profile_web.xml"
+ help_topic="profile_web_tab"
+ />
+ <panel
+ name="panel_profile_picks"
+ label="PICKS"
+ layout="topleft"
+ class="panel_profile_picks"
+ filename="panel_profile_picks.xml"
+ help_topic="profile_picks_tab"
+ />
+ <panel
+ name="panel_profile_classifieds"
+ label="CLASSIFIEDS"
+ layout="topleft"
+ class="panel_profile_classifieds"
+ filename="panel_profile_classifieds.xml"
+ help_topic="profile_classified_tab"
+ />
+ <panel
+ name="panel_profile_firstlife"
+ label="REAL LIFE"
+ layout="topleft"
+ class="panel_profile_firstlife"
+ filename="panel_profile_firstlife.xml"
+ help_topic="profile_firstlife_tab"
+ />
+ <panel
+ name="panel_profile_notes"
+ label="MY NOTES"
+ layout="topleft"
+ class="panel_profile_notes"
+ filename="panel_profile_notes.xml"
+ help_topic="profile_notes_tab"
+ />
+ </tab_container>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
new file mode 100644
index 0000000000..9f3b4d9a00
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ height="115"
+ layout="topleft"
+ name="profile_permissions"
+ width="300">
+ <string
+ name="description_string"
+ value="Allow [AGENT_NAME] to:" />
+ <text
+ name="perm_description"
+ value="Allow agent to:"
+ top="1"
+ left="12"
+ right="-6"
+ height="16"
+ follows="top|left"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <check_box
+ name="online_check"
+ label="See when I am online"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="map_check"
+ label="Find me on the world map"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="objects_check"
+ label="Edit, delete or take my objects from my land"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <button
+ name="perms_btn_ok"
+ label="OK"
+ top_pad="5"
+ left="42"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="perms_btn_cancel"
+ label="Cancel"
+ top_delta="0"
+ left_pad="12"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
new file mode 100644
index 0000000000..3b351a3325
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ height="223"
+ width="200"
+ layout="topleft"
+ min_height="128"
+ min_width="128"
+ name="profile_texture">
+ <layout_stack
+ name="preview_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="vertical"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ name="texture_panel"
+ height="196"
+ follows="left|top"
+ auto_resize="true"
+ layout="topleft">
+ <icon
+ name="profile_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ top="5"
+ left="5"
+ bottom="-1"
+ right="-5"/>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="26"
+ auto_resize="false"
+ layout="topleft">
+ <layout_stack
+ name="buttons_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="horizontal"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="close_panel"
+ auto_resize="false"
+ width="112">
+ <button
+ follows="top|left"
+ height="22"
+ label="Close"
+ layout="topleft"
+ left="1"
+ top="0"
+ width="110"
+ name="close_btn"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index d07e3cb31b..343e72f057 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -11,6 +11,11 @@
name="Screenshot">
Screenshot
</floater.string>
+ <floater.string
+ name="chat_report_format">
+Time: [MSG_TIME]
+Text: [MSG_DESCRIPTION]
+ </floater.string>
<texture_picker
allow_no_texture="true"
default_image_name="None"
@@ -19,7 +24,7 @@
layout="topleft"
left="60"
name="screenshot"
- top="15"
+ top="20"
width="220" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_settings_picker.xml b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
index 3a26c3b547..8931269fe7 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -89,7 +89,7 @@
top="1"
right="-4"
bottom="-1"
- filter_asset_type="settings" />
+ filter_asset_types="settings" />
</panel>
</layout_panel>
<layout_panel name="pnl_combo"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index 3a66911389..0cb69137e3 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -138,6 +138,7 @@
word_wrap="true"
visible="false"
width="87" />
+
<filter_editor
follows="left|top|right"
height="23"
@@ -153,22 +154,13 @@
bg_alpha_color="DkGray2"
border="false"
follows="all"
- height="233"
+ height="242"
layout="topleft"
left_delta="0"
name="inventory panel"
top_pad="4"
width="231"
- filter_asset_type="texture"/>
- <check_box
- height="14"
- initial_value="false"
- label="Show folders"
- layout="topleft"
- name="show_folders_check"
- top_pad="0"
- left_delta="-3"
- width="200" />
+ filter_asset_types="texture|material"/>
<!-- middle: local mode -->
<button
@@ -218,8 +210,8 @@
multi_select="true"
search_column="1"
visible="false">
+ <column name="icon" label="" width="20" />
<column name="unit_name" label="Name" dynamicwidth="true" />
- <column name="unit_id_HIDDEN" label="ID" width="0" />
</scroll_list>
<!-- middle: bake mode -->
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 0abee2ff80..4700488197 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="600"
+ height="651"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -68,7 +68,7 @@
</floater.string>
<floater.string
name="status_selectcount">
- [OBJ_COUNT] objects selected, land impact [LAND_IMPACT]
+ [OBJ_COUNT] objects selected, land impact [LAND_IMPACT] [secondlife:///app/openfloater/object_weights More info]
</floater.string>
<floater.string
name="status_remaining_capacity">
@@ -763,11 +763,12 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="selection_count"
+ name="selection_faces"
top_delta="0"
visible="false"
width="280">
- </text>
+ Faces selected: [FACES_STRING]
+ </text>
<text
text_color="LtGray_50"
type="string"
@@ -777,11 +778,10 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="remaining_capacity"
+ name="selection_count"
top_pad="0"
visible="false"
width="280">
- [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights More info]
</text>
<!-- <text -->
<!-- text_color="LtGray_50" -->
@@ -820,7 +820,7 @@
width="282"/>
<tab_container
follows="left|top"
- height="410"
+ height="476"
halign="center"
left="0"
name="Object Info Tabs"
@@ -1430,16 +1430,40 @@ even though the user gets a free copy.
tool_tip="Causes object to not collide with other objects or avatars"
top_pad="0"
width="123" />
- <text
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left_delta="0"
+ name="object_horizontal"
+ top_pad="10"
+ width="95" />
+ <menu_button
+ menu_filename="menu_copy_paste_pos.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_pos_btn"
+ tool_tip="Paste options"
+ width="19"/>
+ <text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
name="label position"
- top_pad="10"
+ tool_tip="Position (meters)"
+ left_pad="8"
+ top_delta="0"
width="121">
- Position (meters)
+ Position (m)
</text>
<spinner
follows="left|top"
@@ -1449,12 +1473,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="512"
min_val="-256"
name="Pos X"
text_enabled_color="1 0 0.3 .7"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1481,21 +1505,36 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
max_val="4096"
+ min_val="-32"
name="Pos Z"
text_enabled_color="0 0.8 1 .65"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_size.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_size_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label size"
- top_pad="6"
+ tool_tip="Size (meters)"
width="121">
- Size (meters)
+ Size (m)
</text>
<spinner
follows="left|top"
@@ -1505,12 +1544,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="64"
min_val="0.01"
name="Scale X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1542,17 +1581,31 @@ even though the user gets a free copy.
text_enabled_color="1 1 1 1"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_rot.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_rot_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label rotation"
- top_pad="10"
+ tool_tip="Rotation (degrees)"
width="121">
- Rotation (degrees)
+ Rotation (°)
</text>
<spinner
decimal_digits="2"
@@ -1563,12 +1616,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="9999"
min_val="-9999"
name="Rot X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
decimal_digits="2"
@@ -1614,13 +1667,23 @@ even though the user gets a free copy.
width="150">
Prim Type
</text>-->
+
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ name="object_vertical"
+ left="117"
+ top="6"
+ height="500"
+ width="0"/>
<combo_box
height="19"
layout="topleft"
name="comboBaseType"
top="6"
left="125"
- width="150">
+ width="125">
<combo_box.item
label="Box"
name="Box"
@@ -1654,13 +1717,26 @@ even though the user gets a free copy.
name="Sculpted"
value="Sculpted" />
</combo_box>
+ <menu_button
+ menu_filename="menu_copy_paste_object.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left_pad="8"
+ top_delta="2"
+ name="clipboard_obj_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left="125"
name="text cut"
top_pad="5"
width="150">
@@ -1700,7 +1776,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text hollow"
- top_pad="6"
+ top_pad="7"
width="68">
Hollow
</text>
@@ -1748,7 +1824,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="Hollow Shape"
- top_pad="4"
+ top_pad="7"
width="150">
Hollow Shape
</text>
@@ -1784,7 +1860,7 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
name="text twist"
- top_pad="5"
+ top_pad="7"
width="150">
Twist (begin/end)
</text>
@@ -1826,12 +1902,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="scale_taper"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1879,7 +1955,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text topshear"
- top_pad="3"
+ top_pad="5"
width="141">
Top Shear
</text>
@@ -1922,12 +1998,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="advanced_cut"
- top_pad="3"
+ top_pad="7"
width="150">
Profile Cut (begin/end)
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1986,7 +2062,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text taper2"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
@@ -2029,7 +2105,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text radius delta"
- top_pad="2"
+ top_pad="7"
width="78">
Radius
</text>
@@ -2157,6 +2233,19 @@ even though the user gets a free copy.
<panel.string name="None">None</panel.string>
<panel.string name="Prim">Prim</panel.string>
<panel.string name="Convex Hull">Convex Hull</panel.string>
+ <menu_button
+ menu_filename="menu_copy_paste_features.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_features_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -2309,6 +2398,15 @@ even though the user gets a free copy.
name="FlexForceZ"
top_pad="4"
width="128" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="10"
+ width="278" />
<check_box
height="16"
@@ -2317,7 +2415,7 @@ even though the user gets a free copy.
left="10"
name="Light Checkbox Ctrl"
tool_tip="Causes object to emit light"
- top_pad="15"
+ top_pad="8"
width="60" />
<color_swatch
can_apply_immediately="true"
@@ -2344,6 +2442,19 @@ even though the user gets a free copy.
name="light texture control"
tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"
width="32" />
+ <menu_button
+ menu_filename="menu_copy_paste_light.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_light_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<spinner
follows="left|top"
height="19"
@@ -2353,7 +2464,7 @@ even though the user gets a free copy.
layout="topleft"
left="10"
name="Light Intensity"
- top_pad="3"
+ top_pad="26"
width="128" />
<spinner bottom_delta="0"
decimal_digits="3"
@@ -2420,7 +2531,70 @@ even though the user gets a free copy.
mouse_opaque="true"
name="Light Ambiance"
width="120" />
- <text
+ <check_box
+ height="16"
+ label="Reflection Probe"
+ layout="topleft"
+ left="10"
+ name="Reflection Probe"
+ tool_tip="Adjusts how objects within this volume receive reflections when PBR is enabled"
+ top_pad="10"
+ width="60" />
+ <combo_box
+ height="19"
+ top_delta="0"
+ left="144"
+ follows="left|top"
+ name="Probe Volume Type"
+ tool_tip="Choose the probe influence volume"
+ width="108">
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Box"
+ name="Box"
+ value="Box"/>
+ </combo_box>
+ <check_box
+ height="16"
+ label="Dynamic"
+ layout="topleft"
+ left="10"
+ name="Probe Dynamic"
+ tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
+ bottom_delta="19"
+ width="60" />
+ <spinner bottom_delta="19"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Ambiance"
+ label_width="55"
+ left="10"
+ max_val="1"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Ambiance"
+ width="120" />
+ <spinner bottom_delta="0"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Near Clip"
+ label_width="55"
+ left="144"
+ max_val="1024"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Near Clip"
+ width="120" />
+ <text
type="string"
length="1"
follows="left|top"
@@ -2575,7 +2749,7 @@ even though the user gets a free copy.
border_visible="true"
bevel_style="in"
follows="left|top|right"
- height="325"
+ height="387"
layout="topleft"
left="10"
name="contents_inventory"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 83407069d2..c965a4427c 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -14,6 +14,31 @@
single_instance="true"
title="WORLD MAP"
width="650">
+ <string
+ name="collapse_icon"
+ value="map_ui_collapse_icon.png"/>
+ <string
+ name="expand_icon"
+ value="map_ui_expand_icon.png"/>
+ <string
+ name="collapse_tooltip"
+ value="Hide map controls"/>
+ <string
+ name="expand_tooltip"
+ value="Show map controls"/>
+ <layout_stack
+ animate="false"
+ follows="all"
+ name="floater_map_stack"
+ tab_group="1"
+ top="16"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_panel
+ name="map_lp"
+ width="385"
+ height="575">
<panel
filename="panel_world_map.xml"
follows="all"
@@ -21,17 +46,48 @@
layout="topleft"
left="10"
name="objects_mapview"
- top="25"
+ top="6"
width="375" />
+ <panel
+ follows="top|right"
+ height="30"
+ layout="topleft"
+ left_pad="-29"
+ name="expand_btn_panel"
+ background_visible="true"
+ bg_opaque_color="FloaterFocusBackgroundColor"
+ bg_alpha_color="FloaterDefaultBackgroundColor"
+ background_opaque="true"
+ tool_tip="Hide map controls"
+ top="350"
+ width="30">
+ <icon
+ follows="top|right"
+ height="16"
+ width="16"
+ top="7"
+ left="7"
+ scale_image="false"
+ image_name="map_ui_collapse_icon.png"
+ layout="topleft"
+ mouse_opaque="true"
+ name="expand_collapse_icon"
+ tool_tip="Hide map controls" />
+ </panel>
+ </layout_panel>
+ <layout_panel
+ height="575"
+ width="265"
+ expanded_min_dim="265"
+ name="controls_lp">
<panel
- name="layout_panel_1"
- height="22"
- width="238"
- follows="right|top"
- top="25"
- left_pad="5"
- background_visible="true"
- bg_alpha_color="DkGray2">
+ name="layout_panel_1"
+ height="22"
+ width="238"
+ follows="right|top"
+ top="6"
+ background_visible="true"
+ bg_alpha_color="DkGray2">
<text
text_color="White"
font="SansSerifLarge"
@@ -43,17 +99,17 @@
layout="topleft"
left="15"
name="events_label"
- top="3"
width="215">
Legend
</text>
</panel>
-<panel
- follows="right|top"
- height="126"
- top_pad="0"
- width="238"
- name="layout_panel_2">
+ <panel
+ follows="right|top"
+ height="126"
+ top_pad="4"
+ width="238"
+ left="1"
+ name="layout_panel_2">
<button
follows="right|top"
height="22"
@@ -677,6 +733,7 @@
name="zoom_icon"
top_pad="7"
width="16" ></icon>
+ <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->
<slider
follows="left|bottom"
height="16"
@@ -684,10 +741,12 @@
initial_value="-2"
left_pad="0"
layout="topleft"
- max_val="0"
+ max_val="4"
min_val="-8"
name="zoom slider"
show_text="false"
width="200" />
</panel>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index ef4f19cd4c..fceb9b2184 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -85,6 +85,8 @@
use_ellipses="true" />
<text
follows="left|top|right"
+ trusted_content="false"
+ always_show_icons="true"
height="35"
left="8"
name="user_details"
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 9885e37cea..842184de88 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,6 +8,16 @@
tab_stop="false"
name="main_view"
width="1024">
+
+ <!-- At the moment layout_stack is not an LLUICtrl,
+ but Tab requires focus_root to function and focus_root
+ functionality is implemented in LLUICtrl -->
+ <panel follows="all"
+ height="768"
+ name="menu_tab_wrapper"
+ mouse_opaque="false"
+ focus_root="true"
+ top="0">
<layout_stack border_size="0"
follows="all"
mouse_opaque="false"
@@ -18,12 +28,12 @@
<layout_panel mouse_opaque="true"
follows="left|right|top"
name="status_bar_container"
- tab_stop="false"
height="19"
left="0"
top="0"
width="1024"
auto_resize="false"
+ default_tab_group="1"
visible="true">
<view mouse_opaque="false"
follows="all"
@@ -31,13 +41,13 @@
left="0"
top="0"
width="1024"
+ tab_group="1"
height="19"/>
</layout_panel>
<layout_panel auto_resize="false"
height="34"
mouse_opaque="false"
name="nav_bar_container"
- tab_stop="false"
width="1024"
visible="false"/>
<layout_panel auto_resize="true"
@@ -99,6 +109,7 @@
tab_stop="false"/>
</layout_panel>
</layout_stack>
+ </panel> <!--menu_tab_wrapper-->
<panel top="0"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 26b1c86c53..630a1981df 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -13,6 +13,22 @@
function="EnableEdit" />
</menu_item_call>
<menu_item_call
+ label="Edit PBR Material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Save material to inventory"
+ name="SaveGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.SaveGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableSaveGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
enabled="false"
label="Detach item"
layout="topleft"
@@ -33,6 +49,13 @@
function="Object.EnableTouch"
name="EnableTouch"/>
</menu_item_call>
+ <menu_item_call
+ label="Show in inventory"
+ layout="topleft"
+ name="Show original">
+ <menu_item_call.on_click
+ function="Object.ShowOriginal" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 05ab4d35a0..9f394a4c74 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -96,6 +96,13 @@
name="Pay">
<on_click function="AvatarIcon.Action" parameter="pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="AvatarIcon.Action" parameter="report_abuse" />
+ <on_enable function="AvatarIcon.Enable" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index 500b6fffc2..20f3ad080b 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -290,4 +290,11 @@
<menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="View Profile"
+ layout="topleft"
+ name="show_avatar_profile">
+ <menu_item_call.on_click
+ function="Avatar.ToggleMyProfile" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index ed362b36e5..59e6106a28 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -132,6 +132,13 @@
<on_click function="Avatar.DoToSelected" parameter="pay" />
<on_enable function="Avatar.EnableItem" parameter="can_pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <on_click function="Avatar.DoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
new file mode 100644
index 0000000000..4c12180daf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Color Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="color_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
new file mode 100644
index 0000000000..4823d74a26
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Features Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="features_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
new file mode 100644
index 0000000000..5de23dfee3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Light Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="light_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
new file mode 100644
index 0000000000..bdc4537a9d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Object Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="params_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
new file mode 100644
index 0000000000..3ea95b281f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Position Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy position"
+ layout="topleft"
+ name="pos_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste position"
+ layout="topleft"
+ name="pos_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="pos_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
new file mode 100644
index 0000000000..06ce80f897
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Rotation Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy rotation"
+ layout="topleft"
+ name="rot_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste rotation"
+ layout="topleft"
+ name="rot_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
new file mode 100644
index 0000000000..7082a0e65b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Size Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy size"
+ layout="topleft"
+ name="size_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste size"
+ layout="topleft"
+ name="size_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="size_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
new file mode 100644
index 0000000000..f358affc23
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Texture Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="texture_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index 5cae643e44..359c093eff 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -9,7 +9,7 @@
layout="topleft"
name="activate">
<on_click
- function="Gesture.Action.ToogleActiveState" />
+ function="Gesture.Action.ToggleActiveState" />
</menu_item_call>
<menu_item_call
label="Rename"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
index 43287c6ec3..b38fae4404 100644
--- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -79,6 +79,13 @@
</menu_item_call>
<menu_item_separator
layout="topleft"/>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca170813..46dd0ada5d 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -143,264 +143,6 @@
function="Inventory.EmptyLostAndFound"
parameter="rename" />
</menu_item_call>
- <menu_item_call
- label="New Folder"
- layout="topleft"
- name="New Folder">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="category" />
- </menu_item_call>
- <menu_item_call
- label="New Outfit"
- layout="topleft"
- name="New Outfit">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="outfit" />
- </menu_item_call>
- <menu_item_call
- label="New Script"
- layout="topleft"
- name="New Script">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="lsl" />
- </menu_item_call>
- <menu_item_call
- label="New Notecard"
- layout="topleft"
- name="New Note">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="notecard" />
- </menu_item_call>
- <menu_item_call
- label="New Gesture"
- layout="topleft"
- name="New Gesture">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gesture" />
- </menu_item_call>
- <menu
- label="New Clothes"
- layout="topleft"
- name="New Clothes">
- <menu_item_call
- label="New Shirt"
- layout="topleft"
- name="New Shirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- label="New Pants"
- layout="topleft"
- name="New Pants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- label="New Shoes"
- layout="topleft"
- name="New Shoes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- label="New Socks"
- layout="topleft"
- name="New Socks">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- label="New Jacket"
- layout="topleft"
- name="New Jacket">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- label="New Skirt"
- layout="topleft"
- name="New Skirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- label="New Gloves"
- layout="topleft"
- name="New Gloves">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- label="New Undershirt"
- layout="topleft"
- name="New Undershirt">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- label="New Underpants"
- layout="topleft"
- name="New Underpants">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- label="New Alpha Mask"
- layout="topleft"
- name="New Alpha Mask">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_call
- label="New Tattoo"
- layout="topleft"
- name="New Tattoo">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- label="New Universal"
- layout="topleft"
- name="New Universal">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="universal" />
- </menu_item_call>
- <menu_item_call
- label="New Physics"
- layout="topleft"
- name="New Physics">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="physics" />
- </menu_item_call>
- </menu>
- <menu
- label="New Body Parts"
- layout="topleft"
- name="New Body Parts">
- <menu_item_call
- label="New Shape"
- layout="topleft"
- name="New Shape">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="shape" />
- </menu_item_call>
- <menu_item_call
- label="New Skin"
- layout="topleft"
- name="New Skin">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="skin" />
- </menu_item_call>
- <menu_item_call
- label="New Hair"
- layout="topleft"
- name="New Hair">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="hair" />
- </menu_item_call>
- <menu_item_call
- label="New Eyes"
- layout="topleft"
- name="New Eyes">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="eyes" />
- </menu_item_call>
- </menu>
- <menu
- label="New Settings"
- layout="topleft"
- name="New Settings">
- <menu_item_call
- label="New Sky"
- layout="topleft"
- name="New Sky">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="sky"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- <menu_item_call
- label="New Water"
- layout="topleft"
- name="New Water">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="water"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- <menu_item_call
- label="New Day Cycle"
- layout="topleft"
- name="New Day Cycle">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="daycycle"/>
- <menu_item_call.on_enable
- function="Inventory.EnvironmentEnabled" />
- </menu_item_call>
- </menu>
- <menu
- label="Use as default for"
- layout="topleft"
- name="upload_def">
- <menu_item_call
- label="Image uploads"
- layout="topleft"
- name="Image uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="texture" />
- </menu_item_call>
- <menu_item_call
- label="Sound uploads"
- layout="topleft"
- name="Sound uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="sound" />
- </menu_item_call>
- <menu_item_call
- label="Animation uploads"
- layout="topleft"
- name="Animation uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="animation" />
- </menu_item_call>
- <menu_item_call
- label="Model uploads"
- layout="topleft"
- name="Model uploads">
- <menu_item_call.on_click
- function="Inventory.FileUploadLocation"
- parameter="model" />
- </menu_item_call>
- </menu>
<menu
label="Change Type"
layout="topleft"
@@ -683,6 +425,283 @@
parameter="delete_system_folder" />
</menu_item_call>
<menu_item_separator
+ layout="topleft"
+ name="Create Separator" />
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Outfit"
+ layout="topleft"
+ name="New Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="outfit" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Notecard"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
+ <menu
+ label="New Clothes"
+ layout="topleft"
+ name="New Clothes">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha Mask"
+ layout="topleft"
+ name="New Alpha Mask">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Universal"
+ layout="topleft"
+ name="New Universal">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="universal" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Physics"
+ layout="topleft"
+ name="New Physics">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="physics" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Body Parts"
+ layout="topleft"
+ name="New Body Parts">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Settings"
+ layout="topleft"
+ name="New Settings">
+ <menu_item_call
+ label="New Sky"
+ layout="topleft"
+ name="New Sky">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="sky"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Water"
+ layout="topleft"
+ name="New Water">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="water"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Day Cycle"
+ layout="topleft"
+ name="New Day Cycle">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="daycycle"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Use as default for"
+ layout="topleft"
+ name="upload_def">
+ <menu_item_call
+ label="Image uploads"
+ layout="topleft"
+ name="Image uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="texture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sound uploads"
+ layout="topleft"
+ name="Sound uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="sound" />
+ </menu_item_call>
+ <menu_item_call
+ label="Animation uploads"
+ layout="topleft"
+ name="Animation uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="animation" />
+ </menu_item_call>
+ <menu_item_call
+ label="Model uploads"
+ layout="topleft"
+ name="Model uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="model" />
+ </menu_item_call>
+ <menu_item_call
+ label="PBR material uploads"
+ layout="topleft"
+ name="PBR uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="pbr_material" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
layout="topleft" />
<menu_item_separator
layout="topleft" />
@@ -912,6 +931,25 @@
function="Inventory.DoToSelected"
parameter="apply_settings_parcel" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Subfolder Separator" />
+ <menu_item_call
+ label="Create folder from selected"
+ layout="topleft"
+ name="New folder from selected">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="new_folder_from_selected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Ungroup folder items"
+ layout="topleft"
+ name="Ungroup folder items">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="ungroup_folder_items" />
+ </menu_item_call>
<menu_item_separator
layout="topleft"
name="Marketplace Separator" />
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 3385a29a6c..0e193521a3 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -97,6 +97,14 @@
function="Inventory.DoCreate"
parameter="gesture" />
</menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ </menu_item_call>
<menu
height="175"
label="New Clothes"
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..2715c916d4 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -8,63 +8,109 @@
top="724"
visible="false"
width="128">
- <menu_item_call
- label="Zoom Close"
- name="Zoom Close">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check
+ label="Zoom very close"
+ name="Zoom very close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
+ parameter="very close" />
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="very close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom close"
+ name="Zoom close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="close" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Medium"
- name="Zoom Medium">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom medium"
+ name="Zoom medium">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="medium" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Far"
- name="Zoom Far">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="medium" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom far"
+ name="Zoom far">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="far" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default">
- <menu_item_call.on_click
- function="Minimap.Zoom"
- parameter="default" />
- </menu_item_call>
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="far" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Rotate Map"
- name="Rotate Map">
+ label="North at top"
+ name="North at top">
<menu_item_check.on_check
- control="MiniMapRotate" />
+ function="Minimap.MapOrientation.Check"
+ parameter="north_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapRotate" />
+ function="Minimap.MapOrientation.Set"
+ parameter="north_at_top" />
</menu_item_check>
<menu_item_check
- label="Auto Center"
- name="Auto Center">
+ label="Camera at top"
+ name="Camera at top">
<menu_item_check.on_check
- control="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Check"
+ parameter="camera_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Set"
+ parameter="camera_at_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Show parcel boundaries"
+ name="Show parcel boundaries">
+ <menu_item_check.on_check
+ control="MiniMapShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapShowPropertyLines" />
</menu_item_check>
<menu_item_separator />
+ <menu_item_check
+ label="Auto-center map"
+ name="Auto-center map">
+ <menu_item_check.on_check
+ control="MiniMapAutoCenter" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapAutoCenter" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="Re-center map"
+ name="Re-center map">
+ <menu_item_call.on_click
+ function="Minimap.Center.Activate" />
+ </menu_item_call>
<menu_item_call
- label="Stop Tracking"
- name="Stop Tracking">
+ label="Stop tracking"
+ name="Stop tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
+ label="About Land"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Minimap.AboutLand" />
+ </menu_item_call>
+ <menu_item_call
label="World Map"
name="World Map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index ce34508303..6d37c15815 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -22,6 +22,22 @@
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
+ label="Edit PBR Material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Save material to inventory"
+ name="SaveGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.SaveGLTFMaterial" />
+ <menu_item_call.on_enable
+ function="Object.EnableSaveGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml
new file mode 100644
index 0000000000..4db4d0922b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu">
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="offer_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="offer_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="request_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="request_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="voice_call"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="voice_call"/>
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="View chat history..."
+ layout="topleft"
+ name="chat_history">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="chat_history"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="chat_history"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_chat_history"/>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="add_friend"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="add_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_friend"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="invite_to_group"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Permissions"
+ layout="topleft"
+ name="agent_permissions">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="agent_permissions"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="agent_permissions"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="can_show_on_map"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="can_show_on_map"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="share"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="pay">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="pay"/>
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="block_unblock">
+ <menu_item_check.on_click
+ function="Profile.Commit"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_check
+ function="Profile.CheckItem"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_enable
+ function="Profile.EnableItem"
+ parameter="toggle_block_agent"/>
+ </menu_item_check>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml
new file mode 100644
index 0000000000..d0bd4000f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu Self">
+ <menu_item_call
+ label="Edit Display Name"
+ layout="topleft"
+ name="edit_display_name">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Partner"
+ layout="topleft"
+ name="edit_partner">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_partner"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Upload Photo"
+ layout="topleft"
+ name="upload_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="upload_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="upload_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Change Photo"
+ layout="topleft"
+ name="change_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="change_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="change_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Photo"
+ layout="topleft"
+ name="remove_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_photo"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index e8b6116026..5ca8be2123 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -29,7 +29,14 @@
name="remove_friend">
<menu_item_call.on_click
function="Url.RemoveFriend" />
- </menu_item_call>
+ </menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <menu_item_call.on_click
+ function="Url.ReportAbuse" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 85c20268d0..cb2f24334c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -47,8 +47,7 @@
label="Picks..."
name="Picks">
<menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="picks" />
+ function="ShowAgentProfilePicks" />
</menu_item_call>
<menu_item_call
label="Experiences..."
@@ -423,7 +422,9 @@
</menu_item_call>
<menu_item_call
label="Stop animations"
- name="Stop Animating My Avatar">
+ name="Stop Animating My Avatar"
+ allow_key_repeat="true"
+ shortcut="alt|shift|A">
<menu_item_call.on_click
function="Tools.StopAllAnimations" />
</menu_item_call>
@@ -471,7 +472,7 @@
layout="topleft"
name="Reset Skeleton And Animations">
<menu_item_call.on_click
- function="Avatar.ResetSkeletonAndAnimations" />
+ function="Avatar.ResetSelfSkeletonAndAnimations" />
</menu_item_call>
<menu_item_call
label="Attachment scripts..."
@@ -1417,6 +1418,15 @@ function="World.EnvPreset"
function="Tools.SelectOnlyMovableObjects"
parameter="movable" />
</menu_item_check>
+ <menu_item_check
+ label="Select Invisible Objects"
+ name="Select Invisible Objects">
+ <menu_item_check.on_check
+ control="SelectInvisibleObjects" />
+ <menu_item_check.on_click
+ function="Tools.SelectInvisibleObjects"
+ parameter="invisible" />
+ </menu_item_check>
<menu_item_check
label="Select By Surrounding"
name="Select By Surrounding">
@@ -1574,6 +1584,16 @@ function="World.EnvPreset"
<menu_item_call.on_visible
function="File.VisibleUploadModel"/>
</menu_item_call>
+ <menu_item_call
+ label="Material..."
+ layout="topleft"
+ name="Upload Material">
+ <menu_item_call.on_click
+ function="File.UploadMaterial"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadMaterial" />
+ </menu_item_call>
<menu_item_call
label="Bulk..."
layout="topleft"
@@ -1586,7 +1606,15 @@ function="World.EnvPreset"
parameter="" />
</menu_item_call>
</menu>
- <menu_item_separator/>
+ <menu_item_call
+ label="Material Editor"
+ name="material_editor_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="material_editor" />
+ </menu_item_call>
+
+ <menu_item_separator/>
<menu_item_call
enabled="false"
label="Undo"
@@ -2633,6 +2661,12 @@ function="World.EnvPreset"
function="Advanced.ForceErrorBadMemoryAccess" />
</menu_item_call>
<menu_item_call
+ label="Force Bad Memory Access in Coroutine"
+ name="Force Bad Memory Access in Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccessCoro" />
+ </menu_item_call>
+ <menu_item_call
label="Force Infinite Loop"
name="Force Infinite Loop">
<menu_item_call.on_click
@@ -2898,6 +2932,16 @@ function="World.EnvPreset"
parameter="lights" />
</menu_item_check>
<menu_item_check
+ label="Reflection Probes"
+ name="Reflection Probes">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="reflection probes" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="reflection probes" />
+ </menu_item_check>
+ <menu_item_check
label="Particles"
name="Particles">
<menu_item_check.on_check
@@ -3063,24 +3107,10 @@ function="World.EnvPreset"
<menu_item_check.on_click
function="ToggleControl"
parameter="UseOcclusion" />
- <menu_item_check.on_enable
- function="Advanced.EnableObjectObjectOcclusion" />
</menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Advanced Lighting Model"
- name="Advanced Lighting Model">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderDeferred" />
- </menu_item_check>
- <menu_item_check
label=" Shadows from Sun/Moon/Projectors"
name="Shadows from Sun/Moon/Projectors">
<menu_item_check.on_check
@@ -3107,14 +3137,14 @@ function="World.EnvPreset"
<menu_item_separator />
<menu_item_check
- label="Debug GL"
+ label="Start Debug GL on next run"
name="Debug GL">
<menu_item_check.on_check
function="CheckControl"
- parameter="RenderDebugGL" />
+ parameter="RenderDebugGLSession" />
<menu_item_check.on_click
function="ToggleControl"
- parameter="RenderDebugGL" />
+ parameter="RenderDebugGLSession" />
</menu_item_check>
<menu_item_check
label="Debug Pipeline"
@@ -3236,6 +3266,13 @@ function="World.EnvPreset"
function="ToggleControl"
parameter="RenderHoverGlowEnable" />
</menu_item_check>
+ <menu_item_call
+ enabled="true"
+ label="Rebuild Reflection Probes"
+ name="Rebuild Reflection Probes">
+ <menu_item_call.on_click
+ function="Develop.RebuildReflectionProbes" />
+ </menu_item_call>
<menu_item_separator />
<menu_item_call
@@ -3312,6 +3349,18 @@ function="World.EnvPreset"
function="Advanced.DropPacket" />
</menu_item_call>
</menu>
+ <menu
+ create_jump_keys="true"
+ label="Cache"
+ name="Cache"
+ tear_off="true">
+ <menu_item_call
+ label="Purge Disk Cache"
+ name="Purge Disk Cache">
+ <menu_item_call.on_click
+ function="Advanced.PurgeDiskCache" />
+ </menu_item_call>
+ </menu>
<menu_item_call
label="Dump Scripted Camera"
name="Dump Scripted Camera">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index aa93601669..07ad2838b0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1496,7 +1496,19 @@ Insufficient funds to create classified.
<notification
icon="alertmodal.tga"
- name="DeleteAvatarPick"
+ name="ProfileDeleteClassified"
+ type="alertmodal">
+Delete classified &lt;nolink&gt;[CLASSIFIED]&lt;/nolink&gt;?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProfileDeletePick"
type="alertmodal">
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<tag>confirm</tag>
@@ -1507,6 +1519,32 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
</notification>
<notification
+ icon="alert.tga"
+ name="ProfileUnpublishedClassified"
+ type="alertmodal">
+ You have unpublished classifieds. They will be lost if you close the window.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ProfileUnsavedChanges"
+ type="alertmodal">
+ You have usaved changes.
+ <tag>confirm</tag>
+ <tag>save</tag>
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Discard"
+ yestext="Save"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="DeleteOutfits"
type="alertmodal">
@@ -3907,7 +3945,7 @@ Are you sure you want to return objects owned by [USER_NAME]?
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
<tag>fail</tag>
</notification>
@@ -3918,7 +3956,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
</notification>
<notification
@@ -6764,6 +6802,22 @@ You don&apos;t have permission to view this notecard.
<notification
icon="notifytip.tga"
+ name="MaterialMissing"
+ type="notifytip">
+ Material is missing from database.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="MaterialNoPermissions"
+ type="notifytip">
+ You don&apos;t have permission to view this material.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="RezItemNoPermissions"
type="notifytip">
Insufficient permissions to rez object.
@@ -6795,6 +6849,15 @@ Please try again.
<notification
icon="notifytip.tga"
+ name="UnableToLoadMaterial"
+ type="notifytip">
+ Unable to load material.
+ Please try again.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="ScriptMissing"
type="notifytip">
Script is missing from database.
@@ -9025,7 +9088,64 @@ Unable to upload texture.
[REASON]
<tag>fail</tag>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotUploadMaterial"
+ type="alertmodal">
+There was a problem uploading the file
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Save Material"
+ name="SaveMaterialAs"
+ type="alertmodal">
+ <unique/>
+ Name this material:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidMaterialName"
+ type="alertmodal">
+Please enter a non-empty name
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UsavedMaterialChanges"
+ type="alertmodal">
+ You have unsaved changes.
+ <form name="form">
+ <button
+ index="0"
+ name="discard"
+ text="Discard changes"/>
+ <button
+ index="1"
+ name="keep"
+ text="Keep editing"/>
+ </form>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="LivePreviewUnavailable"
@@ -9040,6 +9160,29 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran
<notification
icon="alertmodal.tga"
+ name="FacePasteFailed"
+ type="alertmodal">
+Paste failed. [REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FacePasteTexturePermissions"
+ type="alertmodal">
+ You applied a texture with limited permissions, object will inherit permissions from texture.
+ <usetemplate
+ ignoretext="Paste: You applied a texture with limited permissions"
+ name="notifyignore"/>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmLeaveCall"
type="alertmodal">
Are you sure you want to leave this call?
@@ -9699,6 +9842,15 @@ Attempt cancelled.
<notification
icon="alertmodal.tga"
+ name="LocalGLTFVerifyFail"
+ persist="true"
+ type="notify">
+Attempted to add an invalid or unreadable GLTF material [FNAME] which could not be opened or decoded.
+Attempt cancelled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="PathfindingReturnMultipleItems"
type="alertmodal">
You are returning [NUM_ITEMS] items. Are you sure you want to continue?
@@ -11640,7 +11792,7 @@ This Region does not support environmental settings.
<notification
icon="alertmodal.tga"
- label="Save Outfit"
+ label="Save Environmental Settings"
name="SaveSettingAs"
type="alertmodal">
<unique/>
@@ -11819,4 +11971,44 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
</form>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ label="Create subfolder"
+ name="CreateSubfolder"
+ type="alertmodal">
+ <unique/>
+ Name the new folder:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="SameFolderRequired"
+ type="alert">
+ Selected items must be in the same folder.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+<notification
+ icon="notifytip.tga"
+ name="MaterialCreated"
+ type="notifytip">
+Material successfully created. Asset ID: [ASSET_ID]
+</notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index aa1b929412..54f038c24f 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -155,6 +155,7 @@
right="-3"
mouse_opaque="true"
name="speaking_indicator"
+ tool_tip="Voice volume"
visible="true"
width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index d4a2745d1d..04a0bc800d 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -38,28 +38,15 @@
name="auto_renew_off">
Disabled
</panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
height="26"
layout="topleft"
- left_pad="4"
+ left="12"
name="title"
text_color="LtGray"
- top="0"
+ top="2"
value="Classified Info"
use_ellipses="true"
width="275" />
@@ -420,7 +407,7 @@
height="23"
label="Teleport"
layout="topleft"
- left="0"
+ left="2"
name="teleport_btn"
top="0"
width="101" />
@@ -443,24 +430,6 @@
top="0"
width="100" />
</layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top="0"
- width="101" />
- </layout_panel>
</layout_stack>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
deleted file mode 100644
index e846edf1d4..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ /dev/null
@@ -1,354 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Classified"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_classified"
- help_topic="profile_edit_classified"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <string name="publish_label">
- Publish
- </string>
- <string name="save_label">
- Save
- </string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="0"
- width="250">
- Edit Classified
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="502"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- reserve_scroll_corner="false"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="690"
- left="0"
- width="285">
- <panel
- name="snapshot_panel"
- layout="topleft"
- follows="left|top|right"
- height="197"
- left="10"
- top="10"
- width="272">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- top="0"
- left="0"
- name="classified_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="0"
- left="0"
- width="272" />
- </panel>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="30"
- name="classified_name"
- prevalidate_callback="ascii"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="256"
- name="classified_desc"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="30"
- layout="topleft"
- left="10"
- name="classified_location"
- right="-10"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="10"
- top_pad="5"
- name="set_to_curr_location_btn"
- width="200" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="category_label"
- text_color="white"
- top_pad="15"
- value="Category:"
- width="250" />
- <combo_box
- follows="left|top"
- height="23"
- label=""
- left="10"
- name="category"
- top_pad="5"
- width="156" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="content_type_label"
- text_color="white"
- top_pad="15"
- value="Content type:"
- width="250" />
- <icons_combo_box
- follows="left|top"
- height="23"
- label="General Content"
- layout="topleft"
- left="10"
- name="content_type"
- top_pad="5"
- width="156">
- <icons_combo_box.drop_down_button
- image_overlay="Parcel_PG_Light"
- image_overlay_alignment="left"
- imgoverlay_label_space="3"
- pad_left="3"/>
- <icons_combo_box.item
- label="Moderate Content"
- name="mature_ci"
- value="Mature">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_M_Light"
- width="20"/>
- </icons_combo_box.item>
- <icons_combo_box.item
- label="General Content"
- name="pg_ci"
- value="PG">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_PG_Light"
- width="20"/>
- </icons_combo_box.item>
- </icons_combo_box>
- <check_box
- height="16"
- label="Auto renew each week"
- layout="topleft"
- left="10"
- name="auto_renew"
- top_pad="15"
- width="250" />
- <text
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="price_for_listing_label"
- text_color="white"
- top_pad="15"
- value="Price for listing:"
- width="250" />
- <spinner
- decimal_digits="0"
- follows="left|top"
- halign="left"
- height="23"
- increment="1"
- label_width="20"
- label="L$"
- v_pad="10"
- layout="topleft"
- left="10"
- value="50"
- min_val="50"
- max_val="99999"
- name="price_for_listing"
- top_pad="5"
- tool_tip="Price for listing."
- width="105" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="303">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_panel_ls"
- left="1"
- orientation="horizontal"
- top_pad="0"
- width="309">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="save_changes_btn_lp"
- auto_resize="true"
- width="156">
- <button
- follows="bottom|left|right"
- height="23"
- label="[LABEL]"
- layout="topleft"
- name="save_changes_btn"
- left="1"
- top="0"
- width="155" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="157">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- left="1"
- top="0"
- width="156" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
deleted file mode 100644
index 357a5559bf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Pick"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_pick"
- help_topic="profile_edit_pick"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="4"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="4"
- width="250">
- Edit Pick
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="501"
- layout="topleft"
- left="8"
- top_pad="9"
- name="profile_scroll"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="500"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- no_commit_on_selection="true"
- top="10"
- left="11"
- name="pick_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="10"
- left="11"
- width="286" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="63"
- name="pick_name"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- hide_scrollbar="false"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- spellcheck="true"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="50"
- layout="topleft"
- left="10"
- name="pick_location"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="8"
- top_pad="0"
- name="set_to_curr_location_btn"
- width="200" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="315">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="150">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Pick"
- layout="topleft"
- name="save_changes_btn"
- top="0"
- left="1"
- width="149" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left_pad="4"
- name="layout_panel2"
- auto_resize="true"
- width="146">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- top="0"
- left="1"
- width="145" />
- </layout_panel>
- </layout_stack>
-
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
deleted file mode 100644
index 2c7c8133d1..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ /dev/null
@@ -1,472 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- class="edit_profile_panel"
- follows="all"
- height="585"
- label="Profile Edit"
- layout="topleft"
- left="0"
- name="edit_profile_panel"
- top="0"
- width="313">
- <string
- name="CaptionTextAcctInfo">
- [ACCTTYPE]
-[PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string
- name="RegisterDateFormat">
- [REG_DATE] ([AGE])
- </string>
- <string
- name="AcctTypeResident"
- value="Resident" />
- <string
- name="AcctTypeTrial"
- value="Trial" />
- <string
- name="AcctTypeCharterMember"
- value="Charter Member" />
- <string
- name="AcctTypeEmployee"
- value="Linden Lab Employee" />
- <string
- name="PaymentInfoUsed"
- value="Payment Info Used" />
- <string
- name="PaymentInfoOnFile"
- value="Payment Info On File" />
- <string
- name="NoPaymentInfoOnFile"
- value="No Payment Info On File" />
- <string
- name="AgeVerified"
- value="Age-verified" />
- <string
- name="NotAgeVerified"
- value="Not Age-verified" />
- <string
- name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=en
- </string>
- <string
- name="my_account_link_url">
- http://secondlife.com/my
- </string>
- <string
- name="no_partner_text"
- value="None" />
- <scroll_container
- color="DkGray2"
- follows="all"
- height="537"
- min_height="300"
- layout="topleft"
- left="8"
- width="292"
- name="profile_scroll"
- reserve_scroll_corner="true"
- opaque="true"
- top="10">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <panel
- name="data_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="display_name_label"
- text_color="LtGray"
- value="Display Name:"
- width="80" />
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="solo_username_label"
- text_color="LtGray"
- value="Username:"
- visible="false"
- width="80" />
- <button
- name="set_name"
- layout="topleft"
- follows="top|left"
- image_overlay="Edit_Wrench"
- top="21"
- left="10"
- height="23"
- width="23"
- tool_tip="Set Display Name"/>
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="10"
- name="solo_user_name"
- text_color="white"
- top_delta="3"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- width="275" />
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="43"
- name="user_name"
- text_color="white"
- top_delta="0"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="true"
- width="250" />
- <text
- follows="top|left"
- font="SansSerifBold"
- height="20"
- layout="topleft"
- left_delta="0"
- name="user_name_small"
- text_color="white"
- top_delta="-4"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- wrap="true"
- width="245" />
- <text
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="user_label"
- text_color="LtGray"
- top_pad="8"
- value="Username:"
- width="70" />
- <text
- follows="top|left"
- height="20"
- layout="topleft"
- left_pad="0"
- name="user_slid"
- text_color="EmphasisColor"
- font="SansSerifBold"
- top_delta="-2"
- translate="false"
- use_ellipses="true"
- value="teststring.pleaseignore"
- wrap="true"
- width="205" />
- <panel
- name="lifes_images_panel"
- follows="left|top|right"
- height="244"
- layout="topleft"
- top="65"
- left="0"
- width="292">
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- left="10"
- name="second_life_image_panel"
- top="0"
- width="282">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top="10"
- name="second_life_photo_title_text"
- text_color="white"
- value="[SECOND_LIFE]:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="default_profile_picture.j2c"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="2nd_life_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="2nd_life_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- </panel>
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- top="90"
- max_length="512"
- name="sl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- top_pad="5"
- left="10"
- name="first_life_image_panel"
- width="285">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top_pad="10"
- name="real_world_photo_title_text"
- text_color="white"
- value="Real World:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="Generic_Person_Large"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="real_world_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="real_world_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- max_length="512"
- top="223"
- name="fl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_homepage_text"
- text_color="white"
- top_pad="10"
- width="100">
- Homepage:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left="10"
- top_pad="0"
- value="http://"
- name="homepage_edit"
- width="272">
- </line_editor>
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_acc_status_text"
- text_color="white"
- top_pad="10"
- value="My Account:"
- width="100" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="28"
- layout="topleft"
- left="10"
- name="acc_status_text"
- read_only="true"
- top_pad="5"
- v_pad="0"
- value="Resident. No payment info on file."
- width="200"
- word_wrap="true" />
- <text
- type="string"
- follows="left|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left="10"
- name="my_account_link"
- value="[[URL] Go to My Dashboard]"
- width="200" />
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_partner_text"
- text_color="white"
- top_pad="10"
- value="My Partner:"
- width="150" />
- <panel
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="partner_data_panel"
- width="200">
- <text
- follows="left|top|right"
- height="12"
- initial_value="(retrieving)"
- layout="topleft"
- left="0"
- name="partner_text"
- top="0"
- use_ellipses="true"
- width="280"/>
- </panel>
- <text
- follows="left|top"
- height="15"
- layout="topleft"
- link="true"
- left="10"
- name="partner_edit_link"
- value="[[URL] Edit]"
- width="70" />
- </panel>
- </panel>
- </scroll_container>
- <panel
- follows="bottom|left|right"
- height="28"
- left="0"
- name="profile_me_buttons_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- name="bottom_panel_ls"
- left="7"
- orientation="horizontal"
- top_pad="0"
- width="295">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="save_changes_btn_lp"
- top="0"
- auto_resize="true"
- width="153">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Changes"
- layout="topleft"
- left="1"
- name="save_btn"
- top="0"
- width="152" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- top="0"
- auto_resize="true"
- width="154">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left="1"
- name="cancel_btn"
- top="0"
- width="153" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index e34335a2af..5eafb5cdf1 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -95,6 +95,7 @@ Hover your mouse over the options for more help.
layout="topleft"
max_length="511"
name="charter"
+ parse_urls="true"
top="105"
right="-4"
bg_readonly_color="DkGray2"
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b72af7221e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="group_list_item"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+>
+ <icon
+ name="hovered_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Over"
+ visible="false"
+ />
+ <icon
+ name="selected_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Select"
+ visible="false"
+ />
+ <group_icon
+ name="group_icon"
+ top="2"
+ left="5"
+ height="14"
+ width="14"
+ image_name="Generic_Group"
+ mouse_opaque="true"
+ use_draw_context_alpha="false"
+ />
+ <text
+ name="group_name"
+ value="Unknown"
+ top="2"
+ left_pad="5"
+ right="-2"
+ height="16"
+ follows="left|right"
+ layout="topleft"
+ parse_urls="false"
+ text_color="ScrollUnselectedColor"
+ use_ellipses="true"
+ />
+ <button
+ name="visibility_hide_btn"
+ tool_tip="Hide group on my profile"
+ top_delta="-3"
+ left_pad="3"
+ right="-53"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_Off_Pressed"
+ image_unselected="Profile_Group_Visibility_Off"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="visibility_show_btn"
+ tool_tip="Show group on my profile"
+ top_delta="0"
+ right_delta="0"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_On_Pressed"
+ image_unselected="Profile_Group_Visibility_On"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="info_btn"
+ tool_tip="More info"
+ top_delta="2"
+ left_pad="3"
+ right="-30"
+ height="16"
+ width="16"
+ follows="right"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ tab_stop="false"
+ />
+ <!--*TODO: Should only appear on rollover-->
+ <button
+ name="profile_btn"
+ tool_tip="View profile"
+ top_delta="-2"
+ left_pad="5"
+ right="-3"
+ height="20"
+ width="20"
+ follows="right"
+ layout="topleft"
+ image_overlay="Web_Profile_Off"
+ tab_stop="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index ade004f9d0..3aba80909a 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -145,7 +145,7 @@
follows="left|top"
font="SansSerifMedium"
text_color="EmphasisColor"
- height="16"
+ height="24"
left="408"
bottom_delta="0"
label="Remember password"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 5568ccb792..d36c83d292 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -98,7 +98,7 @@
auto_resize="false"
follows="left|right|top"
name="widget_container"
- width="532"
+ width="730"
left="0"
top="0"
height="80">
@@ -106,7 +106,7 @@
allow_text_entry="true"
follows="left|bottom"
height="32"
- left="2"
+ left="42"
label="Username"
combo_editor.font="SansSerifLarge"
max_chars="128"
@@ -126,7 +126,7 @@
follows="left|top"
width="200"
height="32"
- left="220"
+ left="262"
max_length_chars="16"
name="password_edit"
label="Password"
@@ -145,42 +145,58 @@
label_color="White"
font="SansSerifLarge"
name="connect_btn"
- left="432"
- width="100"
+ left_pad="15"
+ width="120"
height="32"
top="0" />
+ <text
+ follows="left|top"
+ font="SansSerifLarge"
+ font.style="BOLD"
+ text_color="EmphasisColor"
+ height="34"
+ name="sign_up_text"
+ left_pad="10"
+ top="0"
+ width="200"
+ valign="center">
+ Sign up
+ </text>
<check_box
- control_name="RememberPassword"
follows="left|top"
font="SansSerifLarge"
- left="0"
+ left="42"
top="32"
height="24"
label="Remember me"
+ word_wrap="down"
check_button.bottom="3"
- name="remember_check"
- width="145" />
- <text
+ name="remember_name"
+ tool_tip="Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames."
+ width="198" />
+ <check_box
+ control_name="RememberPassword"
follows="left|top"
font="SansSerifLarge"
text_color="EmphasisColor"
- height="16"
- name="forgot_password_text"
- left="219"
- top="34"
- width="200">
- Forgotten password
- </text>
+ height="24"
+ left="262"
+ bottom_delta="0"
+ label="Remember password"
+ word_wrap="down"
+ check_button.bottom="3"
+ name="remember_password"
+ width="198" />
<text
follows="left|top"
font="SansSerifLarge"
text_color="EmphasisColor"
height="16"
- name="sign_up_text"
- left="432"
+ name="forgot_password_text"
+ left="492"
top="34"
width="200">
- Sign up
+ Forgotten password
</text>
</layout_panel>
<layout_panel
@@ -216,24 +232,17 @@
auto_resize="false"
follows="left|right|top"
name="images_container"
- width="832"
+ width="675"
left="0"
top="0"
height="500">
<icon
- height="400"
- width="400"
- image_name="first_login_image_left"
+ height="450"
+ width="675"
+ image_name="first_login_image"
left="0"
name="image_left"
top="0" />
- <icon
- height="400"
- width="400"
- image_name="first_login_image_right"
- left_pad="32"
- name="image_right"
- top="0" />
</layout_panel>
<layout_panel
height="100"
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
deleted file mode 100644
index 23e7814cad..0000000000
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- border="false"
- follows="all"
- height="570"
- label="My Profile"
- layout="topleft"
- left="0"
- name="panel_me"
- top="0"
- width="333">
- <panel
- class="panel_picks"
- filename="panel_picks.xml"
- label="MY PICKS"
- help_topic="panel_my_picks_tab"
- name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 1c9aa1eb83..b44c19810b 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -4,7 +4,6 @@
background_visible="true"
bg_opaque_color="MouseGray"
follows="left|top|right"
- focus_root="true"
height="34"
layout="topleft"
name="navigation_bar"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
deleted file mode 100644
index 99c47eb825..0000000000
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- follows="all"
- height="570"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_pick_info"
- help_topic="profile_pick_info"
- top="0"
- width="333">
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="2"
- value="Pick Info"
- use_ellipses="true"
- width="275" />
- <scroll_container
- color="DkGray2"
- opaque="true"
- follows="all"
- height="503"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="400"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- enabled="false"
- follows="left|top|right"
- height="197"
- layout="topleft"
- left="11"
- name="pick_snapshot"
- top="10"
- width="272" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="35"
- width="280"
- layout="topleft"
- font="SansSerifBig"
- font.style="BOLD"
- left="10"
- top_pad="10"
- name="pick_name"
- read_only="true"
- text_color="white"
- v_pad="0"
- value="[name]"
- use_ellipses="true" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="25"
- layout="topleft"
- left="10"
- name="pick_location"
- read_only="true"
- width="280"
- word_wrap="true"
- v_pad="0"
- value="[loading...]" />
- <text_editor
- bg_readonly_color="DkGray2"
- follows="all"
- height="100"
- width="280"
- parse_urls="true"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- read_only="true"
- text_readonly_color="white"
- value="[description]"
- wrap="true" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- layout="topleft"
- top_pad="5"
- left="8"
- name="buttons">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="312">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- top="0"
- width="101" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="100">
- <button
- follows="bottom|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- top_pad="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top_pad="0"
- width="101" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
deleted file mode 100644
index 8def96cada..0000000000
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- follows="all"
- height="571"
- label="Picks"
- layout="topleft"
- left="8"
- name="panel_picks"
- top_pad="0"
- width="313">
- <string
- name="no_picks"
- value="No Picks" />
- <string
- name="no_classifieds"
- value="No Classifieds" />
- <text
- type="string"
- follows="all"
- height="535"
- layout="topleft"
- left="6"
- name="picks_panel_text"
- wrap="true"
- top="10"
- width="313"/>
- <accordion
- fit_parent="true"
- follows="all"
- height="514"
- layout="topleft"
- left="0"
- name="accordion"
- top="0"
- single_expansion="true"
- width="313">
- <accordion_tab
- layout="topleft"
- height="235"
- min_height="150"
- name="tab_picks"
- title="Picks"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="picks_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="235"
- name="tab_classifieds"
- title="Classifieds"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="classifieds_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- </accordion>
- <panel
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- bevel_style="none"
- enabled="false"
- follows="bottom|left|right"
- left="1"
- height="27"
- label="bottom_panel"
- layout="topleft"
- name="edit_panel"
- top_pad="0"
- width="312">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="edit_panel_ls"
- left="10"
- orientation="horizontal"
- top_pad="0"
- width="293">
-
- <layout_panel
- follows="bottom|left"
- height="18"
- layout="bottomleft"
- left="0"
- name="gear_menu_btn"
- auto_resize="true"
- width="51">
- <button
- follows="bottom|left"
- height="18"
- image_disabled="AddItem_Disabled"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- layout="topleft"
- left="0"
- name="new_btn"
- tool_tip="Create a new pick or classified at the current location"
- top="0"
- width="18" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|right"
- height="18"
- layout="bottomleft"
- name="trash_btn_lp"
- auto_resize="true"
- width="18">
- <button
- follows="bottom|right"
- height="18"
- image_disabled="TrashItem_Disabled"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- name="trash_btn"
- top="0"
- width="18" />
- </layout_panel>
-
- </layout_stack>
- </panel>
-
- <panel
- bg_opaque_color="DkGray"
- background_visible="true"
- background_opaque="true"
- follows="bottom|left|right"
- layout="topleft"
- left="0"
- height="30"
- name="buttons_cucks"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="2"
- name="buttons_cucks_ls"
- orientation="horizontal"
- top="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="0"
- name="info_btn_lp"
- auto_resize="true"
- top="0"
- width="95">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Info"
- layout="topleft"
- name="info_btn"
- tab_stop="false"
- tool_tip="Show pick information"
- width="95" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- left_pad="2"
- name="teleport_btn_lp"
- auto_resize="true"
- width="117">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tab_stop="false"
- tool_tip="Teleport to the corresponding area"
- width="117" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- name="show_on_map_btn_lp"
- auto_resize="true"
- left_pad="2"
- width="90">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- tab_stop="false"
- tool_tip="Show the corresponding area on the World Map"
- width="88" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 5aff7a5127..38d364cf9a 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -231,34 +231,6 @@
m
</text>
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="30"
- name="WindLightUseAtmosShaders"
- top_delta="24"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="30"
- name="UseLightShaders"
- top_delta="24"
- width="256">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
<slider
control_name="IndirectMaxComplexity"
tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
@@ -274,7 +246,7 @@
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
- top_delta="60"
+ top_delta="36"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 67eff2b762..08ff3d4d53 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -126,6 +126,31 @@
type="string"
length="1"
follows="left|top"
+ height="12"
+ layout="topleft"
+ left="37"
+ name="title_pbr"
+ top_pad="7"
+ width="100">
+ PBR Materials
+ </text>
+ <text
+ type="string"
+ use_ellipses="true"
+ follows="left|top"
+ height="27"
+ layout="topleft"
+ font.style="BOLD"
+ left="37"
+ name="upload_pbr"
+ top_pad="5"
+ width="370"
+ word_wrap="true"/>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
height="30"
layout="topleft"
font.style="ITALIC"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
new file mode 100644
index 0000000000..c9e8b242d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classified"
+ top="0"
+ left="0"
+ height="420"
+ width="315"
+ follows="all"
+ layout="topleft"
+ help_topic="panel_profile_classified"
+ min_height="250"
+>
+ <panel.string
+ name="type_mature"
+ >
+ Moderate
+ </panel.string>
+ <panel.string
+ name="type_pg"
+ >
+ General Content
+ </panel.string>
+ <panel.string
+ name="l$_price"
+ >
+ L$[PRICE]
+ </panel.string>
+ <panel.string
+ name="click_through_text_fmt"
+ >
+ [TELEPORT] teleport, [MAP] map, [PROFILE] profile
+ </panel.string>
+ <panel.string
+ name="date_fmt"
+ >
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string
+ name="auto_renew_on"
+ >
+ Enabled
+ </panel.string>
+ <panel.string
+ name="auto_renew_off"
+ >
+ Disabled
+ </panel.string>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+ <string
+ name="publish_label"
+ >
+ Publish
+ </string>
+ <string
+ name="save_label"
+ >
+ Save
+ </string>
+
+ <layout_stack
+ name="main_classifieds_stack"
+ top="0"
+ bottom="-1"
+ left="0"
+ width="310"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ width="310"
+ height="300"
+ layout="topleft"
+ name="scroll_layout_panel"
+ auto_resize="true">
+ <scroll_container
+ name="profile_scroll"
+ top="0"
+ left="0"
+ height="300"
+ width="310"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ name="info_scroll_content_panel"
+ top="0"
+ left="0"
+ height="562"
+ width="280"
+ follows="left|top|right"
+ layout="topleft"
+ background_visible="false"
+ min_height="200"
+ >
+ <texture_picker
+ name="classified_snapshot"
+ enabled="false"
+ top="0"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <icon
+ name="edit_icon"
+ label=""
+ tool_tip="Click to select an image"
+ top="0"
+ left="0"
+ height="161"
+ width="260"
+ layout="topleft"
+ follows="left|top"
+ image_name="spacer24.tga"
+ visible="false"
+ />
+ <layout_stack
+ name="info_panel"
+ top="145"
+ left="0"
+ height="375"
+ width="310"
+ follows="all"
+ layout="topleft"
+ visible="true"
+ animate="false"
+ orientation="vertical"
+ >
+ <layout_panel
+ name="main_info_panel"
+ top="0"
+ left="0"
+ height="160"
+ width="280"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text_editor
+ name="classified_name"
+ top="0"
+ left="10"
+ height="35"
+ width="270"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ font="SansSerifBig"
+ font.style="BOLD"
+ h_pad="0"
+ read_only="true"
+ text_color="white"
+ use_ellipses="true"
+ v_pad="0"
+ >
+ [name]
+ </text_editor>
+ <text
+ name="classified_location_label"
+ value="Location:"
+ top_pad="-2"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_location"
+ value="[loading...]"
+ top_pad="5"
+ left="10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ <text
+ name="content_type_label"
+ value="Content Type:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icon
+ name="content_type_moderate"
+ top_pad="-11"
+ left_pad="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_M_Light"
+ />
+ <icon
+ name="content_type_general"
+ top_delta="0"
+ left_delta="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_PG_Light"
+ />
+ <text_editor
+ name="content_type"
+ value="[content type]"
+ top_delta="1"
+ left_pad="2"
+ height="18"
+ width="130"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="category"
+ value="[category]"
+ top_pad="-10"
+ left_pad="0"
+ height="18"
+ width="150"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="creation_date_label"
+ value="Creation date:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="creation_date"
+ value="[date]"
+ tool_tip="Creation date"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="price_for_listing_label"
+ value="Price for listing:"
+ top_pad="5"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="price_for_listing"
+ tool_tip="Price for listing."
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="105"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ >
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="clickthrough_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="click_through_label"
+ value="Clicks:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="click_through_text"
+ value="[clicks]"
+ tool_tip="Click through data"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ </layout_panel>
+ <layout_panel
+ name="auto_renew_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="auto_renew_label"
+ value="Auto renew:"
+ top="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text
+ name="auto_renew"
+ value="Enabled"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="top|left"
+ layout="topleft"
+ />
+ </layout_panel>
+ <layout_panel
+ name="descr_layout_panel"
+ top="0"
+ left="0"
+ height="220"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="true"
+ >
+ <text
+ name="classified_desc_label"
+ value="Description:"
+ top="0"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_desc"
+ trusted_content="false"
+ value="[description]"
+ top_pad="7"
+ left="10"
+ height="200"
+ width="280"
+ follows="all"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ max_length="1023"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ </layout_panel>
+ </layout_stack>
+ <panel
+ name="edit_panel"
+ top="145"
+ left="0"
+ height="420"
+ width="320"
+ follows="left|top|right"
+ layout="topleft"
+ visible="false"
+ >
+ <text
+ name="Name:"
+ top="0"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="classified_name_edit"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ font="SansSerif"
+ max_length_bytes="30"
+ prevalidate_callback="ascii"
+ commit_on_focus_lost="false"
+ text_color="black"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="classified_desc_edit"
+ top_pad="2"
+ left="10"
+ height="100"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ max_length="256"
+ text_color="black"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <text
+ name="classified_location_edit"
+ top_pad="2"
+ left="10"
+ right="-10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ length="1"
+ type="string"
+ word_wrap="true"
+ >
+ loading...
+ </text>
+ <button
+ name="set_to_curr_location_btn"
+ label="Set to Current Location"
+ top_pad="5"
+ left="10"
+ height="23"
+ width="200"
+ follows="left|top"
+ layout="topleft"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <combo_box
+ name="category_edit"
+ label=""
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ />
+ <text
+ name="content_type_label"
+ value="Content type:"
+ top_pad="15"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icons_combo_box
+ name="content_type_edit"
+ label="General Content"
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ layout="topleft"
+ >
+ <icons_combo_box.drop_down_button
+ image_overlay="Parcel_PG_Light"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="3"
+ pad_left="3"
+ />
+ <icons_combo_box.item
+ name="mature_ci"
+ label="Moderate Content"
+ value="Mature"
+ >
+ <item.columns
+ value="Parcel_M_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ name="pg_ci"
+ label="General Content"
+ value="PG"
+ >
+ <item.columns
+ value="Parcel_PG_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ </icons_combo_box>
+ <check_box
+ name="auto_renew_edit"
+ label="Auto renew each week"
+ top_pad="10"
+ left="10"
+ height="16"
+ width="250"
+ layout="topleft"
+ />
+ </panel>
+ </panel>
+ </scroll_container>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ width="310"
+ height="25"
+ layout="topleft"
+ name="util_buttons_lp"
+ auto_resize="true">
+ <layout_stack
+ name="util_buttons_stack"
+ bottom="-1"
+ left="1"
+ right="-1"
+ height="25"
+ follows="left|bottom|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="teleport_btn_lp"
+ auto_resize="false"
+ top="0"
+ width="85">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ top="0"
+ left="0"
+ height="23"
+ max_width="101"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="show_on_map_btn"
+ label="Map"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="edit_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="edit_btn"
+ label="Edit"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ width="310"
+ height="41"
+ layout="topleft"
+ name="publish_layout_panel"
+ auto_resize="false">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="publish_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="publish_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="save_changes_btn"
+ label="[LABEL]"
+ top="0"
+ left="0"
+ left_pad="5"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="cancel_btn"
+ label="Cancel"
+ top="0"
+ left="0"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2b2f60e0c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classifieds"
+ label="Classified"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_classifieds"
+ value="No Classifieds"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new classified at the current location"
+ enabled="false"
+ top="25"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected classified"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_classifieds"
+ top="0"
+ bottom="-1"
+ left="4"
+ right="-4"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ tab_width="150"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="classifieds_panel_text"
+ top="250"
+ left="110"
+ right="-110"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..ca1e405a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_firstlife"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="5"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <icon
+ name="real_world_pic"
+ image_name="Generic_Person_Large"
+ follows="top|left"
+ layout="topleft"
+ top="10"
+ left="8"
+ height="160"
+ width="160"/>
+ <loading_indicator
+ name="image_upload_indicator"
+ top="79"
+ left="77"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ <button
+ name="fl_upload_image"
+ label="Upload Photo"
+ top="102"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_change_image"
+ label="Change Photo"
+ top_pad="5"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_remove_image"
+ label="Remove Photo"
+ top_pad="5"
+ left_delta="0"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <text_editor
+ name="fl_description_edit"
+ trusted_content="false"
+ enabled="false"
+ top="180"
+ left="6"
+ right="-6"
+ height="224"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ <button
+ name="fl_save_changes"
+ label="Save"
+ top_pad="5"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+ <button
+ name="fl_discard_changes"
+ label="Discard"
+ top_delta="0"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
new file mode 100644
index 0000000000..16e7365042
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_notes"
+ label="Notes &amp; Privacy"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="3"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <text
+ name="status_message"
+ value="Make notes about this person here. No one else can see your notes."
+ top="6"
+ left="6"
+ right="-6"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <text_editor
+ name="notes_edit"
+ enabled="false"
+ top="28"
+ left="6"
+ right="-6"
+ bottom="-26"
+ follows="all"
+ layout="topleft"
+ max_length="65530"
+ word_wrap="true"
+ />
+ <button
+ name="notes_save_changes"
+ label="Save"
+ bottom="-1"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+ <button
+ name="notes_discard_changes"
+ label="Discard"
+ bottom="-1"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
new file mode 100644
index 0000000000..3e91640093
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_pick_info"
+ top="0"
+ left="0"
+ height="360"
+ width="310"
+ follows="all"
+ layout="topleft"
+ help_topic="profile_pick_info"
+>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+
+ <layout_stack
+ name="main_pick_stack"
+ left="1"
+ right="-1"
+ top="0"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="main_pick_lp"
+ auto_resize="true"
+ height="314">
+ <texture_picker
+ name="pick_snapshot"
+ top="10"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <text
+ name="title_label"
+ top_pad="-15"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="pick_name"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="290"
+ follows="left|right|top"
+ layout="topleft"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="pick_desc"
+ trusted_content="false"
+ always_show_icons="true"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="45"
+ width="290"
+ follows="all"
+ layout="topleft"
+ allow_html="true"
+ border_visible="true"
+ h_pad="4"
+ max_length="1023"
+ v_pad="3"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ bottom="-25"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|right|bottom"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <line_editor
+ name="pick_location"
+ enabled="false"
+ bottom="-1"
+ left="10"
+ height="23"
+ width="290"
+ follows="left|right|bottom"
+ layout="topleft"
+ length="1"
+ type="string"
+ >
+ Loading...
+ </line_editor>
+ </layout_panel>
+
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="25">
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="0"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="show_on_map_btn"
+ label="Show on Map"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="tp_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="41">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="save_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="create_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="create_changes_btn"
+ label="Create Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="save_changes_btn"
+ label="Save Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="cancel_changes_btn"
+ label="Cancel"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
new file mode 100644
index 0000000000..44d5c448c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_picks"
+ label="Picks"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_picks"
+ value="No Picks"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="header_text"
+ top="5"
+ left="5"
+ right="-5"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ >
+ Tell everyone about your favorite places in Second Life.
+ </text>
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new pick at the current location"
+ enabled="false"
+ top_pad="4"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected pick"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_picks"
+ top="0"
+ bottom="-5"
+ left="4"
+ right="-4"
+ tab_width="150"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="picks_panel_text"
+ top="250"
+ left="100"
+ right="-100"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..551b477876
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="date_format"
+ value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" />
+ <string
+ name="age_format"
+ value="[AGE]" />
+ <string
+ name="partner_text"
+ value="Partner: [LINK]" />
+ <string
+ name="CaptionTextAcctInfo">
+Account: [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+
+ <layout_stack
+ name="image_stack"
+ top="8"
+ left="6"
+ bottom="-1"
+ width="160"
+ border_size="0"
+ follows="left|top|bottom"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="image_panel"
+ follows="all"
+ layout="topleft"
+ width="160"
+ height="160"
+ auto_resize="false"
+ user_resize="false">
+
+ <icon
+ name="2nd_life_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ interactable="true"
+ top="0"
+ left="2"
+ bottom="-1"
+ right="-1"/>
+
+ <loading_indicator
+ name="image_upload_indicator"
+ top="69"
+ left="69"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ </layout_panel>
+
+ <layout_panel
+ name="basics_panel"
+ follows="all"
+ layout="topleft"
+ height="54"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <line_editor
+ name="user_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top="4"
+ left="3"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="sl_birth_date"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="user_age"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ </layout_panel>
+ <layout_panel
+ name="partner_layout"
+ follows="all"
+ layout="topleft"
+ height="30"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ <text
+ type="string"
+ name="partner_link"
+ value="Partner: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="28"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ use_ellipses="true"
+ word_wrap="true"
+ visible="true"/>
+ </layout_panel>
+
+ <layout_panel
+ name="partner_spacer_layout"
+ follows="all"
+ layout="topleft"
+ height="14"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ </layout_panel>
+
+ <layout_panel
+ name="frind_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <text
+ name="frind_text"
+ value="You are friends"
+ text_color="ConversationFriendColor"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="online_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="online_icon"
+ image_name="Profile_Friend_Online"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="online_text"
+ value="Online"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="offline_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="offline_icon"
+ image_name="Profile_Friend_Offline"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="offline_text"
+ value="Offline"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="account_layout"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="account_info"
+ value="Account: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ word_wrap="true"/>
+ </layout_panel>
+ <layout_panel
+ name="indicator_stack"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ left="67"
+ top="0"
+ height="23"
+ width="23"
+ follows="left|top"
+ layout="topleft"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="settings_panel"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <!-- only for self -->
+ <text
+ name="search_label"
+ value="Show my profile in search:"
+ top="1"
+ left="6"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <combo_box
+ name="show_in_search"
+ tool_tip="Let people see you in search results"
+ left="1"
+ top="18"
+ height="23"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ enabled="false">
+ <combo_box.item
+ name="Hide"
+ label="Hide"
+ value="0" />
+ <combo_box.item
+ name="Show"
+ label="Show"
+ value="1" />
+ </combo_box>
+ </layout_panel>
+
+ <layout_panel
+ name="menu_panel"
+ follows="all"
+ layout="topleft"
+ height="55"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <menu_button
+ layout="topleft"
+ follows="left|top"
+ left="1"
+ top="25"
+ height="25"
+ width="140"
+ label="Actions"
+ halign="left"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_On"
+ image_pressed="DropDown_Press"
+ image_pressed_selected="DropDown_Press"
+ image_disabled="DropDown_Disabled"
+ name="agent_actions_menu" />
+ </layout_panel>
+ </layout_stack>
+
+ <layout_stack
+ name="main_stack"
+ top="8"
+ left="168"
+ bottom="-1"
+ right="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="display_name_panel"
+ follows="all"
+ layout="topleft"
+ height="24"
+ auto_resize="false"
+ user_resize="false">
+ <line_editor
+ name="display_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ font="SansSerifBigLarge"
+ top="0"
+ left="6"
+ height="19"
+ right="-86"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <icon
+ tool_tip="Friend can see my online status"
+ mouse_opaque="true"
+ name="can_see_online"
+ image_name="Profile_Perm_Online_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see my online status"
+ mouse_opaque="true"
+ name="cant_see_online"
+ image_name="Profile_Perm_Online_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can see me on map"
+ mouse_opaque="true"
+ name="can_see_on_map"
+ image_name="Profile_Perm_Find_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see me on map"
+ mouse_opaque="true"
+ name="cant_see_on_map"
+ image_name="Profile_Perm_Find_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can edit my objects"
+ mouse_opaque="true"
+ name="can_edit_objects"
+ image_name="Profile_Perm_Objects_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not edit my objects"
+ mouse_opaque="true"
+ name="cant_edit_objects"
+ image_name="Profile_Perm_Objects_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ </layout_panel>
+
+ <layout_panel
+ name="about_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text_editor
+ name="sl_description_edit"
+ trusted_content="false"
+ always_show_icons="true"
+ commit_on_focus_lost="false"
+ enabled="false"
+ top="0"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ font="SansSerifSmall"
+ h_pad="2"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="about_buttons_panel"
+ follows="all"
+ layout="topleft"
+ height="34"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="save_description_changes"
+ label="Save"
+ top="1"
+ right="-105"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <button
+ name="discard_description_changes"
+ label="Discard"
+ top="1"
+ right="-1"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="9"
+ width="492"/>
+ </layout_panel>
+
+ <layout_panel
+ name="groups_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text
+ name="group_label"
+ value="Group memberships"
+ top="1"
+ left="2"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <group_list
+ name="group_list"
+ top="18"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ border_visible="true"
+ color="ScrollBgWriteableColor"
+ for_agent="false"/>
+
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_web.xml b/indra/newview/skins/default/xui/en/panel_profile_web.xml
new file mode 100644
index 0000000000..e0cb4d3d06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_web.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_web"
+ label="Web"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <panel.string
+ name="LoadTime"
+ value="Load Time: [TIME] seconds"
+ />
+ <web_browser
+ name="profile_html"
+ top="10"
+ bottom="-18"
+ left="10"
+ right="-10"
+ follows="all"
+ layout="topleft"
+ start_url=""
+ />
+ <text
+ name="status_text"
+ bottom="-4"
+ left="110"
+ right="-110"
+ follows="bottom|left|right"
+ layout="topleft"
+ halign="center"
+ parse_urls="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 8243c2715d..2aaea04a6d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -86,7 +86,7 @@
name="detail_texture_text"
top="110"
width="300">
- Terrain Textures (requires 512x512, 24 bit .tga files)
+ Terrain Textures (requires 1024x1024, 24 bit .tga files)
</text>
<texture_picker
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
index 6f82a0efa1..094be36b01 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -315,6 +315,29 @@
top_delta="20"
width="219"
can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="200">
+ Reflection Probe Ambiance:
+ </text>
+ <slider
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="probe_ambiance"
+ top_delta="20"
+ width="219"
+ can_edit_text="true"/>
</layout_panel>
</layout_stack>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 9023d68ea9..b711ed0e1c 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -11,7 +11,6 @@
mouse_opaque="false"
name="status"
top="19"
- tab_stop="false"
width="1000">
<panel.string
name="packet_loss_tooltip">
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 90f32ae452..104bcb9257 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -2,7 +2,7 @@
<panel
border="false"
follows="all"
- height="420"
+ height="500"
label="Texture"
layout="topleft"
left="0"
@@ -11,6 +11,36 @@
name="Texture"
top="0"
width="295">
+ <panel.string
+ name="paste_error_face_selection_mismatch">
+ When multiple faces are copied, the target object must have the same number of faces selected.
+ </panel.string>
+ <panel.string
+ name="paste_error_object_face_count_mismatch">
+ When all faces of an object are copied, the target object must have the same number of faces.
+ </panel.string>
+ <panel.string
+ name="paste_error_inventory_not_found">
+ One or more texture not found in inventory.
+ </panel.string>
+ <panel.string
+ name="paste_options">
+ Paste options
+ </panel.string>
+
+ <menu_button
+ menu_filename="menu_copy_paste_color.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_color_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -36,7 +66,7 @@
name="colorswatch"
tool_tip="Click to open color picker"
top="20"
- width="64" />
+ width="54" />
<text
type="string"
length="1"
@@ -84,7 +114,7 @@
left_delta="0"
name="glow"
top_pad="4"
- width="80" />
+ width="77" />
<check_box
height="19"
label="Full Bright"
@@ -93,27 +123,39 @@
name="checkbox fullbright"
top_pad="4"
width="81" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="4"
+ width="278" />
<combo_box
height="23"
layout="topleft"
left="10"
name="combobox matmedia"
- top_pad="5"
- width="100">
+ top_pad="17"
+ width="90">
<combo_box.item
label="Materials"
name="Materials"
value="Materials" />
<combo_box.item
+ label="PBR"
+ name="PBR"
+ value="PBR" />
+ <combo_box.item
label="Media"
name="Media"
value="Media" />
</combo_box>
<radio_group
- control_name="ComboMaterialType"
height="50"
layout="topleft"
- left_pad="20"
+ left_pad="5"
top_delta="-10"
width="150"
visible = "false"
@@ -139,7 +181,50 @@
layout="topleft"
top_pad="1"
value="2"/>
- </radio_group>
+ </radio_group>
+ <radio_group
+ height="50"
+ layout="topleft"
+ left_delta="0"
+ top_delta="0"
+ width="150"
+ visible = "false"
+ name="radio_pbr_type">
+ <radio_item
+ label="Color/emissive"
+ name="Color/emissive"
+ top="0"
+ layout="topleft"
+ height="16"
+ value="0"/>
+ <radio_item
+ label="Normal"
+ layout="topleft"
+ top_pad="1"
+ height="16"
+ name="Normal"
+ value="1"/>
+ <radio_item
+ label="Metallic/roughness"
+ name="Metallic/roughness"
+ height="16"
+ layout="topleft"
+ top_pad="1"
+ value="2"/>
+ </radio_group>
+ <menu_button
+ menu_filename="menu_copy_paste_texture.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_texture_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<check_box
control_name="SyncMaterialSettings"
follows="top|left"
@@ -150,7 +235,7 @@
left="8"
name="checkbox_sync_settings"
tool_tip="Adjust all maps repeats simultaneously"
- top_pad="-16"
+ top_pad="19"
width="160" />
<texture_picker
can_apply_immediately="true"
@@ -165,6 +250,17 @@
tool_tip="Click to choose a picture"
top_pad="5"
width="64" />
+ <texture_picker
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="PBR "
+ layout="topleft"
+ left="10"
+ name="pbr_control"
+ tool_tip="Click to choose a pbr material"
+ top_delta="0"
+ width="64" />
<text
type="string"
length="1"
@@ -498,10 +594,7 @@
top_pad="4"
tool_tip="Add Media"
label="Choose..."
- width="85">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
+ width="85"/>
<button
follows="top|left"
height="18"
@@ -511,10 +604,7 @@
tool_tip="Delete this media texture"
top_delta="0"
label="Remove"
- width="85">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
+ width="85"/>
<button
follows="left|top"
height="18"
@@ -771,14 +861,14 @@
top_delta="16"
width="260" />
<button
- left="10"
- top="222"
+ follows="left|top"
+ layout="topleft"
+ left="9"
+ top="204"
height="20"
label="Align"
label_selected="Align current texture layers"
- layout="topleft"
name="button align textures"
- top_delta="0"
tool_tip="Align current texture layers"
width="66" />
<web_browser
@@ -793,4 +883,4 @@
height="4"
start_url="about:blank"
decouple_texture_size="true" />
- </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 8a3e18707f..1c9d750aa6 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -459,7 +459,7 @@
label="Price: L$"
label_width="73"
width="150"
- min_val="1"
+ min_val="0"
height="20"
max_val="999999999"
tool_tip="Object cost." />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index acb3a720b9..9f183d137d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -69,6 +69,7 @@ Voice Server Version: [VOICE_VERSION]
</string>
<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
<string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string>
+ <string name="LocalTime">[month, datetime, local] [day, datetime, local] [year, datetime, local] [hour, datetime, local]:[min, datetime, local]:[second,datetime, local]</string>
<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>
<string name="BuildConfiguration">Build Configuration</string>
@@ -111,7 +112,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="CertAllocationFailure">Failed to allocate openssl memory for certificate.</string>
<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
- <string name="LoginFailed">Login failed.</string>
+ <string name="LoginFailedHeader">Login failed.</string>
<string name="Quit">Quit</string>
<string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string>
@@ -125,6 +126,8 @@ http://secondlife.com/download
For more information, see our FAQ below:
http://secondlife.com/viewer-access-faq</string>
+ <string name="LoginFailed">Grid emergency login failure.
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string>
<string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string>
<string name="LoginFailedAlreadyLoggedIn">This agent is already logged in.
@@ -152,15 +155,18 @@ People with free accounts will not be able to access Second Life during this tim
<string name="LoginFailedComputerProhibited">Second Life cannot be accessed from this computer.
If you feel this is an error, please contact
support@secondlife.com.</string>
+ <!--'Pacific time' placeholder for [TIME] in case time from server can't be decoded-->
+ <string name="PacificTime">Pacific Time</string>
<string name="LoginFailedAcountSuspended">Your account is not accessible until
-[TIME] Pacific Time.</string>
+[TIME].
+If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedAccountDisabled">We are unable to complete your request at this time.
Please contact Second Life support for assistance at http://support.secondlife.com.</string>
<string name="LoginFailedTransformError">Data inconsistency found during login.
Please contact support@secondlife.com.</string>
<string name="LoginFailedAccountMaintenance">Your account is undergoing minor maintenance.
Your account is not accessible until
-[TIME] Pacific Time.
+[TIME].
If you feel this is an error, please contact support@secondlife.com.</string>
<string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string>
<string name="LoginFailedPendingLogout">The system is logging you out right now.
@@ -342,8 +348,6 @@ can be attached to notecards.
<!-- Group name: text shown for LLUUID::null -->
<string name="GroupNameNone">(none)</string>
- <string name="AvalineCaller">Avaline Caller [ORDER]</string>
-
<!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->
<string name="AssetErrorNone">No error</string>
<string name="AssetErrorRequestFailed">Asset request: failed</string>
@@ -399,6 +403,7 @@ http://secondlife.com/support for help fixing this problem.
<string name="symbolic link">link</string>
<string name="symbolic folder link">folder link</string>
<string name="settings blob">settings</string>
+ <string name="render material">material</string>
<string name="mesh">mesh</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
@@ -2336,6 +2341,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
An error occurred while opening Marketplace Listings.
If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
</string>
+ <string name="InventoryMarketplaceConnectionError">
+Marketplace Listings failed to connect.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
+ <string name="InventoryMarketplaceConnectionErrorReason">
+Marketplace Listings failed to connect. Reason: [REASON]
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
<string name="InventoryMarketplaceListingsNoItems">
@@ -2414,6 +2427,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Clothing" value=" Clothing," />
<string name="Gestures" value=" Gestures," />
<string name="Landmarks" value=" Landmarks," />
+ <string name="Materials" value=" Materials," />
<string name="Notecards" value=" Notecards," />
<string name="Objects" value=" Objects," />
<string name="Scripts" value=" Scripts," />
@@ -2459,6 +2473,8 @@ If you continue to receive this message, please contact Second Life support for
<string name="InvFolder Meshes">Meshes</string>
<string name="InvFolder Received Items">Received Items</string>
<string name="InvFolder Merchant Outbox">Merchant Outbox</string>
+ <string name="InvFolder Settings">Settings</string>
+ <string name="InvFolder Materials">Materials</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
<string name="InvFolder Friends">Friends</string>
@@ -2802,10 +2818,14 @@ If you continue to receive this message, please contact Second Life support for
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
- <!-- panel picks -->
- <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
- <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
- <string name="PicksClassifiedsLoadingText">Loading...</string>
+ <!-- panel picks -->
+ <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
+ <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string>
+ <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string>
+ <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
+ <string name="NoAvatarPicksText">This person has no picks</string>
+ <string name="NoAvatarClassifiedsText">This person has no classifieds</string>
+ <string name="PicksClassifiedsLoadingText">Loading...</string>
<!-- Multi Preview Floater -->
<string name="MultiPreviewTitle">Preview</string>
@@ -3835,6 +3855,7 @@ Abuse Report</string>
<string name="New Physics">New Physics</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
+ <string name="New Material">New Material</string>
<string name="New Script">New Script</string>
<string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
@@ -4255,6 +4276,9 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
<string name="ExperiencePermissionShort16">Sit</string>
<string name="ExperiencePermissionShort17">Environment</string>
+ <!-- PBR Materials -->
+ <string name="Material Texture Name Header">Textures present this material: </string>
+
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
index 4f3c177976..87f93e8fcf 100644
--- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Hitos" name="check_landmark"/>
<check_box label="Notas" name="check_notecard"/>
- <check_box label="Redes" name="check_mesh"/>
+ <check_box label="Meshs" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sonidos" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
index b0afd44750..2543508c40 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar al inventario
</floater.string>
- <text name="desc txt">
- Descripción:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Previsualizar la ratio de las proporciones
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta">
- <combo_item name="Unconstrained">
- Sin restricciones
- </combo_item>
- <combo_item name="1:1" tool_tip="Emblema del grupo o perfil del Mundo real">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Perfil de [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Clasificados (también en las listas de búsqueda), hitos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Acerca del terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Destacados del perfil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Guardar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descripción:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Previsualizar la ratio de las proporciones
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Guardar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_profile.xml b/indra/newview/skins/default/xui/es/floater_profile.xml
new file mode 100644
index 0000000000..c9448a0d4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Intereses" name="panel_profile_interests"/>
+ <panel label="Destacados" name="panel_profile_picks"/>
+ <panel label="Clasificado" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Notas" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar cambios en el perfil y cerrar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index c2c996aa8a..2dfaecf3e3 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando el correo electrónico
</string>
+ <string name="facebook_progress_str">
+ Publicando en Facebook
+ </string>
<string name="profile_progress_str">
Publicando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Guardando en el equipo
</string>
+ <string name="facebook_succeeded_str">
+ Imagen subida
+ </string>
<string name="profile_succeeded_str">
Imagen subida
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
¡Guardado en el equipo!
</string>
+ <string name="facebook_failed_str">
+ Error al subir la imagen a tu biografía de Facebook.
+ </string>
<string name="profile_failed_str">
Error al subir la imagen a los comentarios de tu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/es/menu_name_field.xml b/indra/newview/skins/default/xui/es/menu_name_field.xml
new file mode 100644
index 0000000000..0d51fbffeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copiar Nombre mostrado" name="copy_display"/>
+ <menu_item_call label="Copiar Nombre de agente" name="copy_name"/>
+ <menu_item_call label="Copiar ID de agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 54707116d4..36f27bc3c6 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2690,6 +2690,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
index ffad843732..09f87015cc 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/es/panel_facebook_place.xml b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
index 5139bd1d0b..29f6147f23 100644
--- a/indra/newview/skins/default/xui/es/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
@@ -3,7 +3,7 @@
<text name="place_caption_label">
Cuenta algo del lugar donde te encuentras:
</text>
- <check_box initial_value="false" label="Incluir una vista general del lugar" name="add_place_view_cb"/>
+ <check_box initial_value="false" label="Incluye una vista general del lugar" name="add_place_view_cb"/>
<button label="Publicar" name="post_place_btn"/>
<button label="Cancelar" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml
index a17814d15d..ef919f396e 100644
--- a/indra/newview/skins/default/xui/es/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_general.xml
@@ -46,7 +46,7 @@ Deja el cursor sobre las opciones para ver más ayuda.
<check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/>
<check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/>
<spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/>
- <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="La calificación de contenido designa el tipo de contenido y conducta que se permiten en un grupo" width="150">
+ <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si tu grupo contiene información clasificada como Moderada" width="150">
<combo_item name="select_mature">
- Selecciona el nivel de calificación -
</combo_item>
diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..4d682068d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconocido"/>
+ <button name="info_btn" tool_tip="Más información"/>
+ <button name="profile_btn" tool_tip="Ver el perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml
deleted file mode 100644
index 850cd6ec71..0000000000
--- a/indra/newview/skins/default/xui/es/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mi perfil" name="panel_me">
- <panel label="MIS DESTACADOS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 73b9af3665..2aaf7e89be 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Conectado"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Personas de las que podrías querer ser amigo"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classified.xml b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
new file mode 100644
index 0000000000..679026d350
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenido general
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activados
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Inhabilitado
+ </panel.string>
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Guardar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Pulsa para elegir una imagen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Ubicación:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoría:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Fecha de creación:"/>
+ <text_editor name="creation_date" tool_tip="Fecha de creación" value="[date]"/>
+ <text name="price_for_listing_label" value="Precio por publicarlo:"/>
+ <text_editor name="price_for_listing" tool_tip="Precio por publicarlo.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics:"/>
+ <text_editor name="click_through_text" tool_tip="Información sobre Click through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovación:"/>
+ <text name="auto_renew" value="Activados"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descripción:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descripción:
+ </text>
+ <text name="location_label">
+ Ubicación:
+ </text>
+ <text name="classified_location_edit">
+ cargando...
+ </text>
+ <button label="Configurar en mi posición" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoría:"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <icons_combo_box label="Contenido general" name="content_type_edit">
+ <icons_combo_box.item label="Contenido Moderado" name="mature_ci" value="Contenido para adultos"/>
+ <icons_combo_box.item label="Contenido general" name="pg_ci" value="General"/>
+ </icons_combo_box>
+ <check_box label="Renovar automáticamente cada semana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Precio por publicarlo:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Precio por publicarlo." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleporte" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2520348094
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Clasificado" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="No hay clasificados"/>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
index f058ff668b..0fb502e441 100644
--- a/indra/newview/skins/default/xui/fr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Favoris"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_interests.xml b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
new file mode 100644
index 0000000000..86dd63390c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Intereses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quiero:
+ </text>
+ <check_box label="Construye" name="chk0"/>
+ <check_box label="Explora" name="chk1"/>
+ <check_box label="Conoce" name="chk2"/>
+ <check_box label="Encuentra empleo" name="chk6"/>
+ <check_box label="Agrupa" name="chk3"/>
+ <check_box label="Compra" name="chk4"/>
+ <check_box label="Vende" name="chk5"/>
+ <check_box label="Contrata" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitectura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planificación de eventos" name="schk2"/>
+ <check_box label="Preparación de scripts" name="schk4"/>
+ <check_box label="Personajes personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (cargando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_notes.xml b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
new file mode 100644
index 0000000000..4cc14e1487
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notas y Privacidad" name="panel_notes">
+ <text name="status_message" value="Notas privadas en este avatar:"/>
+ <text name="status_message2" value="Permitir que este avatar:"/>
+ <check_box label="Ver cuándo estoy conectado" name="status_check"/>
+ <check_box label="Encontrarme en el mapa del mundo" name="map_check"/>
+ <check_box label="Edita, borrar o tomar mis objetos" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_pick.xml b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
new file mode 100644
index 0000000000..4e9f5bbdd5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <line_editor name="pick_location">
+ Cargando...
+ </line_editor>
+ <button label="Teleporte" name="teleport_btn"/>
+ <button label="Mostrar en el mapa" name="show_on_map_btn"/>
+ <button label="Establecer ubicación" name="set_to_curr_location_btn" tool_tip="Configurar en mi posición"/>
+ <button label="Guardar" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
new file mode 100644
index 0000000000..0641b72c13
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destacados" name="panel_picks">
+ <string name="no_picks" value="No hay destacados"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Cuéntale a todos sobre tus lugares favoritos de Second Life.
+ </text>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..541593660d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Actualmente en línea
+ </string>
+ <string name="status_offline">
+ Actualmente sin conexión
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Ninguno"/>
+ <string name="no_group_text" value="Ninguno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desarrollador"/>
+ <string name="FSSupp" value="Soporte"/>
+ <string name="FSQualityAssurance" value="Buscador de fallos"/>
+ <string name="FSGW" value="Portal"/>
+ <text name="name_label" value="Nombre:"/>
+ <button label="Nombre:" name="set_name" tool_tip="Configurar nombre mostrado"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(cargando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status Desconocido"/>
+ <text name="label" value="Fecha de nacimiento en Second Life:"/>
+ <text name="label2" value="Cuenta:"/>
+ <text name="partner_label" value="Compañero/a:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invitar al grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Acerca de:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar objeto:"/>
+ <text name="Give inventory" tool_tip="Soltar elementos de inventario aquí para dárselos a esta persona.">
+ Soltar aquí el nuevo elemento de inventario.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Encontrar en el mapa" label_selected="Encontrar en el mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pagar a este Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Ofrecer teleporte" label_selected="Ofrecer teleporte" name="teleport" tool_tip="Ofrecer teleporte al residente"/>
+ <button label="Mensaje instantáneo" label_selected="Mensaje instantáneo" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Añadir como amigo" label_selected="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear al residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear al residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar en la búsqueda" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_web.xml b/indra/newview/skins/default/xui/es/panel_profile_web.xml
new file mode 100644
index 0000000000..f9a8f4b113
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tiempo de carga: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (cargando..)
+ </line_editor>
+ <flyout_button label="Cargar" name="load" tool_tip="Cargar esta página de perfil con el navegador incorporado.">
+ <flyout_button.item label="Abrir navegador in-viewer" name="open_item"/>
+ <flyout_button.item label="Abrir navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Perfil web emergente"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index cb6c03dbb5..9aba5299cb 100644
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
@@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Límite de bajada del
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas del terreno (requiere archivos .tga de 512x512, 24 bits)
- </text>
+ Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits)
+ </text>
<text name="height_text_lbl">
1 (bajo)
</text>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index e5598978ce..5a03e65b49 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -178,7 +178,7 @@ Versión del servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Error en el inicio de sesión.
</string>
<string name="Quit">
@@ -348,6 +348,24 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="TestingDisconnect">
Probando la desconexión del visor
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando con Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando de Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema al conectar con Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema al publicar en Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema al desconectar de Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectándose a Flickr...
</string>
@@ -662,9 +680,6 @@ pueden adjuntarse a las notas.
<string name="GroupNameNone">
(ninguno)
</string>
- <string name="AvalineCaller">
- Avaline: [ORDER]
- </string>
<string name="AssetErrorNone">
No hay ningún error
</string>
@@ -2549,9 +2564,21 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="NoPicksClassifiedsText">
No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.
</string>
+ <string name="NoPicksText">
+ No has creado destacados. Haz clic en el botón Más para crear uno.
+ </string>
+ <string name="NoClassifiedsText">
+ No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
El usuario no tiene clasificados ni destacados
</string>
+ <string name="NoAvatarPicksText">
+ El usuario no tiene destacados
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ El usuario no tiene clasificados
+ </string>
<string name="PicksClassifiedsLoadingText">
Cargando...
</string>
@@ -4469,6 +4496,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="share_alert">
Arrastra los ítems desde el invenbtario hasta aquí
</string>
+ <string name="facebook_post_success">
+ Has publicado en Facebook.
+ </string>
<string name="flickr_post_success">
Has publicado en Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_facebook.xml b/indra/newview/skins/default/xui/fr/floater_facebook.xml
index f5097e7a88..f6e8696e53 100644
--- a/indra/newview/skins/default/xui/fr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/fr/floater_facebook.xml
@@ -10,6 +10,6 @@
Erreur
</text>
<text name="connection_loading_text">
- Chargement...
+ En cours de chargement...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
index d63d9903ec..46703fe612 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copier dans l&apos;inventaire
</floater.string>
- <text name="desc txt">
- Description :
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Rapport d&apos;aspect fixe
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe">
- <combo_item name="Unconstrained">
- Sans contraintes
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo du groupe ou profil dans la vie réelle">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profil [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Petites annonces, repères">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="À propos du terrain">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Favoris du profil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Jeter" name="Discard"/>
- <button label="Enregistrer sous" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Description :
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Rapport d&apos;aspect fixe
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Jeter" name="Discard"/>
+ <button label="Enregistrer sous" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_profile.xml b/indra/newview/skins/default/xui/fr/floater_profile.xml
new file mode 100644
index 0000000000..c4af79e946
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Centres d&apos;intérêt" name="panel_profile_interests"/>
+ <panel label="Favoris" name="panel_profile_picks"/>
+ <panel label="Petite annonce" name="panel_profile_classifieds"/>
+ <panel label="Vie réelle" name="panel_profile_firstlife"/>
+ <panel label="Remarques" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Enregistrer les changements apportés au profil et fermer"/>
+ <button label="Annuler" label_selected="Annuler" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 8eb05dd945..adb98a68d2 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Envoi par e-mail
</string>
+ <string name="facebook_progress_str">
+ Publication sur Facebook
+ </string>
<string name="profile_progress_str">
Publication
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Enregistrement sur l&apos;ordinateur
</string>
+ <string name="facebook_succeeded_str">
+ Image chargée
+ </string>
<string name="profile_succeeded_str">
Image chargée
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Enregistrement sur l&apos;ordinateur effectué !
</string>
+ <string name="facebook_failed_str">
+ Échec de chargement de l&apos;image dans votre journal Facebook.
+ </string>
<string name="profile_failed_str">
Échec de chargement de l&apos;image sur le flux de votre profil.
</string>
diff --git a/indra/newview/skins/default/xui/fr/menu_name_field.xml b/indra/newview/skins/default/xui/fr/menu_name_field.xml
new file mode 100644
index 0000000000..6c3fba4110
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copier le Nom d&apos;affichage" name="copy_display"/>
+ <menu_item_call label="Copier le Nom de l&apos;agent" name="copy_name"/>
+ <menu_item_call label="Copier l&apos;ID de l&apos;agent" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index e84de375d8..09905f4e5d 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2683,6 +2683,9 @@ Veuillez sélectionner un terrain plus petit.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
index 7b58f2e825..b892d25f26 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annuler" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
index 319737a2af..0e36c2092c 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life !"/>
+ <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life aujourd&apos;hui !"/>
<string name="facebook_friends_no_connected" value="Vous n&apos;êtes pas connecté(e) à Facebook. Allez à l&apos;onglet Statut pour vous connecter et activer cette fonctionnalité."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amis SL"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
index 3236f35b55..cc4045bc74 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
@@ -4,14 +4,14 @@
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
<combo_box.item label="640 x 480" name="640x480"/>
<combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="1 200 x 630" name="1200x630"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtres d&apos;image">
+ <combo_box name="filters_combobox" tool_tip="Filtres d’image">
<combo_box.item label="Aucun filtre" name="NoFilter"/>
</combo_box>
<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquer pour actualiser"/>
- <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour activer/désactiver l&apos;aperçu"/>
+ <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour basculer l&apos;aperçu"/>
<text name="caption_label">
Commentaire (facultatif) :
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
index 9afa42d2aa..dc8e4b9ecc 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
@@ -6,7 +6,7 @@
Pas connecté(e) à Facebook.
</text>
<panel name="panel_buttons">
- <button label="Connexion..." name="connect_btn"/>
+ <button label="Connexion en cours..." name="connect_btn"/>
<button label="Déconnexion" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Apprenez comment publier sur Facebook]
diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b1b32af7c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Inconnu"/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
+ <button name="profile_btn" tool_tip="Voir le profil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
deleted file mode 100644
index 5676986228..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mon profil" name="panel_me">
- <panel label="MES FAVORIS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 3be6bae52a..e096b5cfe0 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -40,6 +40,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="En ligne"/>
<accordion_tab name="tab_all" title="Tout"/>
+ <accordion_tab name="tab_suggested_friends" title="Personnes avec lesquelles vous aimeriez peut-être devenir ami(e)"/>
</accordion>
</panel>
<panel label="GROUPES" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classified.xml b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
new file mode 100644
index 0000000000..b223684c60
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Modéré
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenu Général
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] téléporter, [MAP] carte, [PROFILE] profile
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activé
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Désactivé
+ </panel.string>
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <string name="publish_label">
+ Publier
+ </string>
+ <string name="save_label">
+ Enregistrer
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Cliquer pour sélectionner une image"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Endroit :"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Date de création :"/>
+ <text_editor name="creation_date" tool_tip="Date de création" value="[date]"/>
+ <text name="price_for_listing_label" value="Coût de l&apos;annonce :"/>
+ <text_editor name="price_for_listing" tool_tip="Coût de l’annonce.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics :"/>
+ <text_editor name="click_through_text" tool_tip="Parcourir les données en cliquant" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renouv. auto :"/>
+ <text name="auto_renew" value="Activé"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Description :"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titre :
+ </text>
+ <text name="description_label">
+ Description :
+ </text>
+ <text name="location_label">
+ Endroit :
+ </text>
+ <text name="classified_location_edit">
+ en cours de chargement...
+ </text>
+ <button label="Définir sur l’emplacement actuel" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <icons_combo_box label="Contenu Général" name="content_type_edit">
+ <icons_combo_box.item label="Contenu Modéré" name="mature_ci" value="Adulte"/>
+ <icons_combo_box.item label="Contenu Général" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Renouvellement auto toutes les semaines" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Coût de l&apos;annonce :"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Coût de l’annonce." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Téléportation" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Carte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifier" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annuler" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..adb3501422
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Petite annonce" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Pas de petites annonces"/>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
index 255aa5dcdc..0f65090209 100644
--- a/indra/newview/skins/default/xui/es/floater_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destacados"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_interests.xml b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
new file mode 100644
index 0000000000..e8212817d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Centres d&apos;intérêt" name="panel_profile_interests">
+ <text name="I Want To:">
+ Je veux :
+ </text>
+ <check_box label="Construire" name="chk0"/>
+ <check_box label="Explorer" name="chk1"/>
+ <check_box label="Rencontrer" name="chk2"/>
+ <check_box label="Être recruté" name="chk6"/>
+ <check_box label="Grouper" name="chk3"/>
+ <check_box label="Acheter" name="chk4"/>
+ <check_box label="Vendre" name="chk5"/>
+ <check_box label="Louer" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Skills:">
+ Compétences :
+ </text>
+ <check_box label="Textures" name="schk0"/>
+ <check_box label="Architecture" name="schk1"/>
+ <check_box label="Modèle" name="schk3"/>
+ <check_box label="Planification des événements" name="schk2"/>
+ <check_box label="Langage de scripts" name="schk4"/>
+ <check_box label="Personnages personnalisés" name="schk5"/>
+ <line_editor name="skills_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Languages:">
+ Langues :
+ </text>
+ <line_editor name="languages_edit">
+ (en cours de chargement...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
new file mode 100644
index 0000000000..03fb37d72b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notes &amp; respect de la vie privée" name="panel_notes">
+ <text name="status_message" value="Notes personnelles sur cet avatar:"/>
+ <text name="status_message2" value="Autoriser cet avatar à :"/>
+ <check_box label="Voir quand je suis en ligne" name="status_check"/>
+ <check_box label="Me trouver sur la carte du monde" name="map_check"/>
+ <check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_pick.xml b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
new file mode 100644
index 0000000000..017fcff88a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <line_editor name="pick_location">
+ En cours de chargement...
+ </line_editor>
+ <button label="Téléportation" name="teleport_btn"/>
+ <button label="Voir sur la carte" name="show_on_map_btn"/>
+ <button label="Définir l&apos;emplacement" name="set_to_curr_location_btn" tool_tip="Définir sur l’emplacement actuel"/>
+ <button label="Enregistrer les favoris" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
new file mode 100644
index 0000000000..1644722813
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoris" name="panel_picks">
+ <string name="no_picks" value="Pas de favoris"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Faites connaître aux autres résidents vos endroits favoris dans Second Life.
+ </text>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..de9cbf6dce
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Actuellement connecté
+ </string>
+ <string name="status_offline">
+ Actuellement déconnecté
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Aucun"/>
+ <string name="no_group_text" value="Aucun"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Développeur"/>
+ <string name="FSSupp" value="Assistance"/>
+ <string name="FSQualityAssurance" value="Suivi des anomalies"/>
+ <string name="FSGW" value="Portail"/>
+ <text name="name_label" value="Nom :"/>
+ <button label="Nom :" name="set_name" tool_tip="Définir un nom d&apos;affichage"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(en cours de chargement...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Statut inconnu"/>
+ <text name="label" value="Date de naissance dans Second Life :"/>
+ <text name="label2" value="Compte :"/>
+ <text name="partner_label" value="Partenaire :"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Groupes :"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Inviter dans le groupe"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="À propos :"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Donner des objets :"/>
+ <text name="Give inventory" tool_tip="Placer les objets de l&apos;inventaire ici pour les donner à cette personne">
+ Placer les objets de l&apos;inventaire ici.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Situer sur la carte" label_selected="Situer sur la carte" name="show_on_map_btn" tool_tip="Localiser le Résident sur la carte"/>
+ <button label="Payer" label_selected="Payer" name="pay" tool_tip="Payer le résident"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Proposer de téléporter" label_selected="Proposer de téléporter" name="teleport" tool_tip="Proposer une téléportation au Résident"/>
+ <button label="Message instantané" label_selected="Message instantané" name="im" tool_tip="Ouvrir une session IM."/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Ajouter un ami" label_selected="Ajouter un ami" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <button label="Bloquer" name="block" tool_tip="Bloquer ce Résident"/>
+ <button label="Débloquer" name="unblock" tool_tip="Débloquer ce Résident"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Afficher avec la recherche" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_web.xml b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
new file mode 100644
index 0000000000..70e145ade9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Heure de chargement : [TIME] secondes"/>
+ <line_editor name="url_edit">
+ (en cours de chargement..)
+ </line_editor>
+ <flyout_button label="Charger" name="load" tool_tip="Charger ce profil avec le navigateur Web incorporé">
+ <flyout_button.item label="Ouvrir dans mon navigateur Web" name="open_item"/>
+ <flyout_button.item label="Ouvrir dans un navigateur externe" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profil de fenêtres web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index 97f486d3a3..bbab00ca24 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite d&apos;abaissement
du terrain" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Textures du terrain (fichiers .tga 512 x 512, 24 bit requis)
- </text>
+ Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis)
+ </text>
<text name="height_text_lbl">
1 (Bas)
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index f7545f08d2..21825c6b2f 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -187,7 +187,7 @@ Voice Server Version: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erreur réseau : impossible d&apos;établir la connexion. Veuillez vérifier votre connexion réseau.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Échec de la connexion.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="TestingDisconnect">
Test de déconnexion du client
</string>
+ <string name="SocialFacebookConnecting">
+ Connexion à Facebook…
+ </string>
+ <string name="SocialFacebookPosting">
+ Publication…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Déconnexion de Facebook…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Un problème est survenu lors de la connexion à Facebook.
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Un problème est survenu lors de la publication sur Facebook.
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Un problème est survenu lors de la déconnexion à Facebook.
+ </string>
<string name="SocialFlickrConnecting">
Connexion à Flickr...
</string>
@@ -674,9 +692,6 @@ peuvent être joints aux notes.
<string name="GroupNameNone">
(aucun)
</string>
- <string name="AvalineCaller">
- Appelant Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Aucune erreur
</string>
@@ -2579,9 +2594,21 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life
<string name="NoPicksClassifiedsText">
Vous n&apos;avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.
</string>
+ <string name="NoPicksText">
+ Vous n&apos;avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori
+ </string>
+ <string name="NoClassifiedsText">
+ Vous n&apos;avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utilisateur n&apos;a ni favoris ni petites annonces.
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utilisateur n&apos;a pas de favoris
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utilisateur n&apos;a pas de petites annonces
+ </string>
<string name="PicksClassifiedsLoadingText">
Chargement...
</string>
@@ -4559,6 +4586,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="share_alert">
Faire glisser les objets de l&apos;inventaire ici
</string>
+ <string name="facebook_post_success">
+ Vous avez publié sur Facebook.
+ </string>
<string name="flickr_post_success">
Vous avez publié sur Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
index 8e8d020067..02f15b6b7b 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copia nell&apos;Inventario
</floater.string>
- <text name="desc txt">
- Descrizione:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Antreprima rapporto di visualizzazione
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso">
- <combo_item name="Unconstrained">
- Libero
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo del gruppo o profilo nel mondo reale">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profilo [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Annunci e inserzioni, punti di riferimento">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Informazioni sul terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Preferiti del Profilo">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Elimina" name="Discard"/>
- <button label="Salva con nome" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrizione:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Antreprima rapporto di visualizzazione
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Elimina" name="Discard"/>
+ <button label="Salva con nome" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_profile.xml b/indra/newview/skins/default/xui/it/floater_profile.xml
new file mode 100644
index 0000000000..7e23f9bbbb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profilo">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessi" name="panel_profile_interests"/>
+ <panel label="Preferiti" name="panel_profile_picks"/>
+ <panel label="Annuncio" name="panel_profile_classifieds"/>
+ <panel label="Vita reale" name="panel_profile_firstlife"/>
+ <panel label="Note" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salva modifiche al profilo e chiudi"/>
+ <button label="Annulla" label_selected="Annulla" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index d21c206f6f..c9f71a167e 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Invio e-mail in corso
</string>
+ <string name="facebook_progress_str">
+ Pubblicazione su Facebook in corso
+ </string>
<string name="profile_progress_str">
Caricamento post
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvataggio sul computer in corso
</string>
+ <string name="facebook_succeeded_str">
+ Immagine caricata
+ </string>
<string name="profile_succeeded_str">
Immagine caricata
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvato sul computer.
</string>
+ <string name="facebook_failed_str">
+ Caricamento immagine sul diario di Facebook non riuscito.
+ </string>
<string name="profile_failed_str">
Caricamento immagine sul feed del profilo non riuscito.
</string>
diff --git a/indra/newview/skins/default/xui/it/menu_name_field.xml b/indra/newview/skins/default/xui/it/menu_name_field.xml
new file mode 100644
index 0000000000..9ac863323c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copia Nome Visualizzato" name="copy_display"/>
+ <menu_item_call label="Copia Nome Agente" name="copy_name"/>
+ <menu_item_call label="Copia ID Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 1c43013255..a69fa07c50 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2685,6 +2685,9 @@ Prova a selezionare una parte di terreno più piccola.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
index ad827696ff..57e422a25b 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annulla" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
index c1c0489f88..28769a010f 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti in Second Life. Invita i tuoi amici di Facebook a partecipare a Second Life!"/>
- <string name="facebook_friends_no_connected" value="Attualmente non sei in collegamento con Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
+ <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti Second Life. Invita ora i tuoi amici di Facebook a unirsi a Second Life!"/>
+ <string name="facebook_friends_no_connected" value="Non sei connesso a Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amici SL"/>
<accordion_tab name="tab_suggested_friends" title="Aggiungi queste persone come amici SL"/>
</accordion>
<text name="facebook_friends_status">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
index 044b8b6164..8d66f35c3c 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
- <combo_box name="resolution_combobox" tool_tip="Risoluzione immagini">
+ <combo_box name="resolution_combobox" tool_tip="Risoluzione immagine">
<combo_box.item label="Finestra attuale" name="CurrentWindow"/>
<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="1200x630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtri immagini">
+ <combo_box name="filters_combobox" tool_tip="Filtri immagine">
<combo_box.item label="Nessun filtro" name="NoFilter"/>
</combo_box>
<button label="Aggiorna" name="new_snapshot_btn" tool_tip="Fai clic per aggiornare"/>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_status.xml b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
index 9b5171043a..7fb1cec78e 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
- <string name="facebook_connected" value="Sei in collegamento con Facebook come:"/>
- <string name="facebook_disconnected" value="Non in collegamento con Facebook"/>
+ <string name="facebook_connected" value="Sei connesso a Facebook come:"/>
+ <string name="facebook_disconnected" value="Non connesso a Facebook"/>
<text name="account_caption_label">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
<panel name="panel_buttons">
- <button label="Collegamento..." name="connect_btn"/>
- <button label="Interrompi collegamento" name="disconnect_btn"/>
+ <button label="Connessione in corso..." name="connect_btn"/>
+ <button label="Disconnetti" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Come pubblicare su Facebook]
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml
index 60028e6098..168524d1ad 100644
--- a/indra/newview/skins/default/xui/it/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_general.xml
@@ -46,7 +46,7 @@ Muovi il tuo mouse sopra le opzioni per maggiore aiuto.
<check_box label="Chiunque può aderire" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di aderire senza essere invitati."/>
<check_box label="Quota di adesione" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa d&apos;iscrizione per aderire al gruppo"/>
<spinner label="L$" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi soci devono pagare questa tassa d&apos;iscrizione quando è selezionata." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Le categorie di accesso definiscono il tipo di contenuti e di comportamenti ammessi in un gruppo">
+ <combo_box name="group_mature_check" tool_tip="Determina se il tuo gruppo contiene informazioni contrassegnate come Moderate opppure no">
<combo_item name="select_mature">
- Seleziona categoria di accesso -
</combo_item>
diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..72e644008c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Sconosciuto"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
+ <button name="profile_btn" tool_tip="Vedi profilo"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml
deleted file mode 100644
index a134f6f1de..0000000000
--- a/indra/newview/skins/default/xui/it/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Il mio profilo" name="panel_me">
- <panel label="I MIEI PREFERITI" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 3df2368ae0..9eb93a26e5 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -40,6 +40,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Tutto"/>
+ <accordion_tab name="tab_suggested_friends" title="Persone che potresti voler aggiungere agli amici"/>
</accordion>
</panel>
<panel label="GRUPPI" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classified.xml b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
new file mode 100644
index 0000000000..3c88fbe92f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderato
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenuto Generale
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletrasporto, [MAP] mappa, [PROFILE] profilo
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Abilitato
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Disabilitato
+ </panel.string>
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <string name="publish_label">
+ Pubblica
+ </string>
+ <string name="save_label">
+ Salva
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Fai clic per selezionare un&apos;immagine"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Posizione:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data di creazione:"/>
+ <text_editor name="creation_date" tool_tip="Data di creazione" value="[date]"/>
+ <text name="price_for_listing_label" value="Prezzo per inserzione:"/>
+ <text_editor name="price_for_listing" tool_tip="Prezzo per inserzione.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clic:"/>
+ <text_editor name="click_through_text" tool_tip="Numero di clic" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Rinnovo automatico:"/>
+ <text name="auto_renew" value="Abilitato"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrizione:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titolo:
+ </text>
+ <text name="description_label">
+ Descrizione:
+ </text>
+ <text name="location_label">
+ Posizione:
+ </text>
+ <text name="classified_location_edit">
+ caricamento in corso...
+ </text>
+ <button label="Imposta come Luogo Attuale" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <icons_combo_box label="Contenuto Generale" name="content_type_edit">
+ <icons_combo_box.item label="Contenuto Moderato" name="mature_ci" value="Per adulti"/>
+ <icons_combo_box.item label="Contenuto Generale" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Rinnovo automatico ogni settimana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Prezzo per inserzione:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Prezzo per inserzione." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletrasporto" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mappa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifica" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annulla" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..6fc0fd0729
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Annuncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nessuno annuncio"/>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..bf8ccef273
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_interests.xml b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
new file mode 100644
index 0000000000..9fe7331e5c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessi" name="panel_profile_interests">
+ <text name="I Want To:">
+ Desidero:
+ </text>
+ <check_box label="Costruire" name="chk0"/>
+ <check_box label="Esplorare" name="chk1"/>
+ <check_box label="Incontrare" name="chk2"/>
+ <check_box label="Essere assunto" name="chk6"/>
+ <check_box label="Gruppo" name="chk3"/>
+ <check_box label="Acquistare" name="chk4"/>
+ <check_box label="Vendere" name="chk5"/>
+ <check_box label="Assumere" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Skills:">
+ Abilità:
+ </text>
+ <check_box label="Texture" name="schk0"/>
+ <check_box label="Architettura" name="schk1"/>
+ <check_box label="Realizzazione modelli 3D" name="schk3"/>
+ <check_box label="Organizzazione eventi" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Personaggi personalizzati" name="schk5"/>
+ <line_editor name="skills_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Languages:">
+ Lingue:
+ </text>
+ <line_editor name="languages_edit">
+ (caricamento in corso...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_notes.xml b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
new file mode 100644
index 0000000000..abd5a347c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Note e Privacy" name="panel_notes">
+ <text name="status_message" value="Annotazioni private su questo avatar:"/>
+ <text name="status_message2" value="Consenti a questo avatar di:"/>
+ <check_box label="Vedere quando sono in linea" name="status_check"/>
+ <check_box label="Trovarmi sulla mappa del mondo" name="map_check"/>
+ <check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_pick.xml b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
new file mode 100644
index 0000000000..5d2b145565
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <line_editor name="pick_location">
+ Caricamento in corso...
+ </line_editor>
+ <button label="Teletrasporto" name="teleport_btn"/>
+ <button label="Mostra sulla mappa" name="show_on_map_btn"/>
+ <button label="Imposta Luogo" name="set_to_curr_location_btn" tool_tip="Imposta come Luogo Attuale"/>
+ <button label="Salva Luogo preferito" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
new file mode 100644
index 0000000000..37cffcf622
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Preferiti" name="panel_picks">
+ <string name="no_picks" value="Nessun preferito"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Comunica a tutti quali sono i tuoi posti preferiti in Second Life.
+ </text>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..47af1960a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile">
+ <string name="status_online">
+ Ora in linea
+ </string>
+ <string name="status_offline">
+ Ora non in linea
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nessuno"/>
+ <string name="no_group_text" value="Nessuno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Sviluppatore"/>
+ <string name="FSSupp" value="Assistenza"/>
+ <string name="FSQualityAssurance" value="Bug Hunter"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Imposta nome visualizzato"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(caricamento in corso...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Stato Sconosciuto"/>
+ <text name="label" value="Compleanno Second Life:"/>
+ <text name="label2" value="Account:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppi:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invita al gruppo:"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Informazioni generali:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Consegna oggetto:"/>
+ <text name="Give inventory" tool_tip="Rilascia gli oggetti dell’inventario per consegnarli a questa persona.">
+ Rilascia l’oggetto dell’inventario qui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Trova sulla mappa" label_selected="Trova sulla mappa" name="show_on_map_btn" tool_tip="Localizza il Residente sulla mappa"/>
+ <button label="Paga" label_selected="Paga" name="pay" tool_tip="Paga del denaro al Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Offri Teletrasporto" label_selected="Offri Teletrasporto" name="teleport" tool_tip="Offri il teletrasporto al Residente"/>
+ <button label="Messaggio istantaneo" label_selected="Messaggio istantaneo" name="im" tool_tip="Apri sessione di messaggistica istantanea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Aggiungi come amico" label_selected="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia al Residente"/>
+ <button label="Blocca" name="block" tool_tip="Blocca questo Residente"/>
+ <button label="Sblocca" name="unblock" tool_tip="Sblocca questo Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostra nella ricerca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_web.xml b/indra/newview/skins/default/xui/it/panel_profile_web.xml
new file mode 100644
index 0000000000..0c3a8ddcf5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tempo di caricamento: [TIME] secondi"/>
+ <line_editor name="url_edit">
+ (caricamento in corso..)
+ </line_editor>
+ <flyout_button label="Carica" name="load" tool_tip="Carica la pagina profilo con il browser Web integrato.">
+ <flyout_button.item label="Apri browser interno" name="open_item"/>
+ <flyout_button.item label="Apri browser esterno" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profilo web a comparsa"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index c61ac3ecce..e08c55f63b 100644
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite di abbassamento
del terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texture terreno (richiede file 512x512, 24 bit .tga)
- </text>
+ Texture terreno (richiede file 1024x1024, 24 bit .tga)
+ </text>
<text name="height_text_lbl">
1 (basso)
</text>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 7690e02692..1ebdadb930 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -183,7 +183,7 @@ Versione server voce: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Accesso non riuscito.
</string>
<string name="Quit">
@@ -353,6 +353,24 @@ Prova ad accedere nuovamente tra un minuto.
<string name="TestingDisconnect">
Verifica scollegamento viewer
</string>
+ <string name="SocialFacebookConnecting">
+ Connessione a Facebook in corso...
+ </string>
+ <string name="SocialFacebookPosting">
+ Caricamento post...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Disconnessione da Facebook in corso...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problemi con la disconnessione da Facebook
+ </string>
<string name="SocialFlickrConnecting">
Collegamento a Flickr...
</string>
@@ -667,9 +685,6 @@ possono essere allegati ai biglietti.
<string name="GroupNameNone">
(nessuno)
</string>
- <string name="AvalineCaller">
- Chiamante Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nessun errore
</string>
@@ -2557,9 +2572,21 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="NoPicksClassifiedsText">
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un&apos;inserzione.
</string>
+ <string name="NoPicksText">
+ Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito.
+ </string>
+ <string name="NoClassifiedsText">
+ Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utente non ha luoghi preferiti né inserzioni
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utente non ha luoghi preferiti
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utente non ha annunci
+ </string>
<string name="PicksClassifiedsLoadingText">
Caricamento in corso...
</string>
@@ -4474,6 +4501,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Offerta cartella di inventario &quot;[ITEM_NAME]&quot;
</string>
+ <string name="facebook_post_success">
+ Hai pubblicato su Facebook.
+ </string>
<string name="flickr_post_success">
Hai pubblicato su Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml
deleted file mode 100644
index 359585eb86..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="ピック"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
index 4617fd1d92..66ef13948a 100644
--- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
インベントリにコピー
</floater.string>
- <text name="desc txt">
- 説明:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- 縦横比のプレビュー
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー">
- <combo_item name="Unconstrained">
- 非拘束
- </combo_item>
- <combo_item name="1:1" tool_tip="グループ記章か現実世界のプロフィール">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] プロフィール">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="クラシファイド広告、検索一覧、ランドマーク">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地情報">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="プロフィールのピック">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="処分する" name="Discard"/>
- <button label="別名で保存" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 説明:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ 縦横比のプレビュー
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="処分する" name="Discard"/>
+ <button label="別名で保存" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_profile.xml b/indra/newview/skins/default/xui/ja/floater_profile.xml
new file mode 100644
index 0000000000..e06cd6e8f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="プロフィール">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="趣味" name="panel_profile_interests"/>
+ <panel label="ピック" name="panel_profile_picks"/>
+ <panel label="クラシファイド広告" name="panel_profile_classifieds"/>
+ <panel label="リアルライフ(現実世界)" name="panel_profile_firstlife"/>
+ <panel label="メモ" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="プロフィールの変更を保存して閉じる"/>
+ <button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index f04193d034..64f292c75c 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
メールの送信
</string>
+ <string name="facebook_progress_str">
+ Facebook へ投稿中
+ </string>
<string name="profile_progress_str">
投稿
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
コンピュータに保存
</string>
+ <string name="facebook_succeeded_str">
+ 画像がアップロードされました
+ </string>
<string name="profile_succeeded_str">
画像がアップロードされました
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
コンピュータに保存されました
</string>
+ <string name="facebook_failed_str">
+ Facebook のタイムラインに画像をアップロードできませんでした。
+ </string>
<string name="profile_failed_str">
プロフィールフィードに画像をアップロードできませんでした。
</string>
diff --git a/indra/newview/skins/default/xui/ja/menu_name_field.xml b/indra/newview/skins/default/xui/ja/menu_name_field.xml
new file mode 100644
index 0000000000..8c37d95073
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="表示名をコピー" name="copy_display"/>
+ <menu_item_call label="エージェント名をコピー" name="copy_name"/>
+ <menu_item_call label="エージェント ID をコピー" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index a66552d3fe..92952f4c8a 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2727,6 +2727,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
index cf5f2489f1..619e9de65a 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="キャンセル" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
index c48f13456b..ee57d178e8 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
@@ -16,5 +16,5 @@
コメント (オプション):
</text>
<button label="投稿" name="post_photo_btn"/>
- <button label="取り消し" name="cancel_photo_btn"/>
+ <button label="キャンセル" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
index 61138f90c1..e97422a9df 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="場所の俯瞰図を含める" name="add_place_view_cb"/>
<button label="投稿" name="post_place_btn"/>
- <button label="取り消し" name="cancel_place_btn"/>
+ <button label="キャンセル" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
index 9d962c9d62..1f48c9c8c7 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
@@ -9,12 +9,12 @@
<button label="接続..." name="connect_btn"/>
<button label="切断" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]
</text>
</panel>
<text name="status_caption_label">
今、何を考えている?
</text>
<button label="投稿" name="post_status_btn"/>
- <button label="取り消し" name="cancel_status_btn"/>
+ <button label="キャンセル" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..77d3d8f391
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="不明"/>
+ <button name="info_btn" tool_tip="詳細"/>
+ <button name="profile_btn" tool_tip="プロフィールの表示"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
deleted file mode 100644
index 9b1cf1c8a4..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="プロフィール" name="panel_me">
- <panel label="マイ ピック" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 0a295855d0..be00a3c122 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="オンライン"/>
<accordion_tab name="tab_all" title="全員"/>
+ <accordion_tab name="tab_suggested_friends" title="友だちになりたくない人"/>
</accordion>
</panel>
<panel label="グループ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classified.xml b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d1bc07e2c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderate
+ </panel.string>
+ <panel.string name="type_pg">
+ General コンテンツ
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] テレポート、 [MAP] 地図、 [PROFILE] プロフィール
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 有効
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 無効
+ </panel.string>
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <string name="publish_label">
+ 掲載
+ </string>
+ <string name="save_label">
+ 保存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="クリックして画像を選択"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="場所:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="制作日:"/>
+ <text_editor name="creation_date" tool_tip="制作日" value="[date]"/>
+ <text name="price_for_listing_label" value="掲載価格:"/>
+ <text_editor name="price_for_listing" tool_tip="掲載価格。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="クリック数:"/>
+ <text_editor name="click_through_text" tool_tip="クリックスルーデータ" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動更新:"/>
+ <text name="auto_renew" value="有効"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="説明:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ タイトル:
+ </text>
+ <text name="description_label">
+ 説明:
+ </text>
+ <text name="location_label">
+ 場所:
+ </text>
+ <text name="classified_location_edit">
+ ロード中...
+ </text>
+ <button label="現在地に設定" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <icons_combo_box label="General コンテンツ" name="content_type_edit">
+ <icons_combo_box.item label="Moderate コンテンツ" name="mature_ci" value="Mature"/>
+ <icons_combo_box.item label="General コンテンツ" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="毎週自動更新" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="掲載価格:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="掲載価格。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="テレポート" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地図" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編集" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="キャンセル" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..1980c0fa62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="クラシファイド広告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="クラシファイド広告なし"/>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..a4ee262cb3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_interests.xml b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
new file mode 100644
index 0000000000..93cde6ffec
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="趣味" name="panel_profile_interests">
+ <text name="I Want To:">
+ 次の内容を実行:
+ </text>
+ <check_box label="作る" name="chk0"/>
+ <check_box label="探検" name="chk1"/>
+ <check_box label="出会う" name="chk2"/>
+ <check_box label="雇ってもらう" name="chk6"/>
+ <check_box label="グループ" name="chk3"/>
+ <check_box label="買う" name="chk4"/>
+ <check_box label="販売する" name="chk5"/>
+ <check_box label="雇う" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Skills:">
+ スキル:
+ </text>
+ <check_box label="テクスチャ" name="schk0"/>
+ <check_box label="建築" name="schk1"/>
+ <check_box label="モデリング" name="schk3"/>
+ <check_box label="イベント計画" name="schk2"/>
+ <check_box label="スクリプト" name="schk4"/>
+ <check_box label="キャラクターのカスタマイズ" name="schk5"/>
+ <line_editor name="skills_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Languages:">
+ 言語:
+ </text>
+ <line_editor name="languages_edit">
+ (ロード中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_notes.xml b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
new file mode 100644
index 0000000000..4b4e0d5e4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="メモとプライバシー" name="panel_notes">
+ <text name="status_message" value="このアバターのプライベートメモ:"/>
+ <text name="status_message2" value="このアバターに次の許可を与える:"/>
+ <check_box label="自分のオンラインステータスを表示する" name="status_check"/>
+ <check_box label="世界地図で自分を探せるようにする" name="map_check"/>
+ <check_box label="自分のオブジェクトを編集・削除・取得できるようにする" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_pick.xml b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
new file mode 100644
index 0000000000..0a20c04ad6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ ロード中...
+ </line_editor>
+ <button label="テレポート" name="teleport_btn"/>
+ <button label="地図に表示" name="show_on_map_btn"/>
+ <button label="場所を設定" name="set_to_curr_location_btn" tool_tip="現在地に設定"/>
+ <button label="ピックを保存" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
new file mode 100644
index 0000000000..4cbfadd09d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ピック" name="panel_picks">
+ <string name="no_picks" value="ピックなし"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life のお気に入りの場所を紹介しましょう。
+ </text>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..5470dc6c82
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile">
+ <string name="status_online">
+ オンライン中
+ </string>
+ <string name="status_offline">
+ オフライン中
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="なし"/>
+ <string name="no_group_text" value="なし"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開発者"/>
+ <string name="FSSupp" value="サポート"/>
+ <string name="FSQualityAssurance" value="バグハンター"/>
+ <string name="FSGW" value="ゲートウェイ"/>
+ <text name="name_label" value="名前:"/>
+ <button label="名前:" name="set_name" tool_tip="表示名を設定"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(ロード中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="ステータス不明"/>
+ <text name="label" value="Second Life 生年月日:"/>
+ <text name="label2" value="アカウント:"/>
+ <text name="partner_label" value="パートナー:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="グループ:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="グループに招待"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="詳細:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="アイテムを渡す:"/>
+ <text name="Give inventory" tool_tip="インベントリのアイテムをここにドロップしてこの人に渡します。">
+ インベントリのアイテムをここにドロップしてください。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="地図上で見つける" label_selected="地図上で見つける" name="show_on_map_btn" tool_tip="住人を地図上で探す"/>
+ <button label="お金を払う" label_selected="お金を払う" name="pay" tool_tip="住人にお金を支払う"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="テレポートを送る" label_selected="テレポートを送る" name="teleport" tool_tip="住人にテレポートを送る"/>
+ <button label="インスタントメッセージ" label_selected="インスタントメッセージ" name="im" tool_tip="インスタントメッセージを開きます"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="フレンド登録" label_selected="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/>
+ <button label="ブロック" name="block" tool_tip="この住人をブロックする"/>
+ <button label="ブロック解除" name="unblock" tool_tip="この住人のブロックを解除する"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="検索に表示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_web.xml b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
new file mode 100644
index 0000000000..4f56a7e98d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="ロード時間:[TIME] 秒"/>
+ <line_editor name="url_edit">
+ (ロード中...)
+ </line_editor>
+ <flyout_button label="ロード" name="load" tool_tip="このプロフィールページを、組み込み Web ブラウザでロードします。">
+ <flyout_button.item label="ビューワ内のブラウザを開く" name="open_item"/>
+ <flyout_button.item label="外部ブラウザを開く" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Web プロフィールのポップアウト"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index fb853c1925..c1080a7d7b 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="地形の上昇限度" name="terrain_raise_spin"/>
<spinner label="地形の下降限度" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形テクスチャ(512x512 の 24 bit .tga ファイル)
- </text>
+ 地形テクスチャ(1024x1024 の 24 bit .tga ファイル)
+ </text>
<text name="height_text_lbl">
1(低)
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index 04dfc0176d..f222a4d61a 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -3,7 +3,7 @@
<button label="ディスクに保存" name="save_to_computer_btn"/>
<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>
<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>
- <button label="Facebook で共有する" name="send_to_facebook_btn"/>
+ <button label="Facebook でシェア" name="send_to_facebook_btn"/>
<button label="Twitter で共有する" name="send_to_twitter_btn"/>
<button label="Flickr で共有する" name="send_to_flickr_btn"/>
<button label="メールにより送信" name="save_to_email_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index b4bc36a800..d90772ab0a 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -186,7 +186,7 @@ LOD 係数: [LOD_FACTOR]
<string name="LoginFailedNoNetwork">
ネットワークエラー:接続を確立できませんでした。お使いのネットワーク接続をご確認ください。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
ログインに失敗しました。
</string>
<string name="Quit">
@@ -356,6 +356,24 @@ support@secondlife.com にお問い合わせください。
<string name="TestingDisconnect">
ビューワの接続を切るテスト中
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook に接続中...
+ </string>
+ <string name="SocialFacebookPosting">
+ 投稿中...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook から切断中...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook への接続時のエラー
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook への投稿時のエラー
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook からの切断時のエラー
+ </string>
<string name="SocialFlickrConnecting">
Flickr に接続中...
</string>
@@ -673,9 +691,6 @@ support@secondlife.com にお問い合わせください。
<string name="GroupNameNone">
(なし)
</string>
- <string name="AvalineCaller">
- Avaline コール [ORDER]
- </string>
<string name="AssetErrorNone">
エラーなし
</string>
@@ -2577,9 +2592,21 @@ support@secondlife.com にお問い合わせください。
<string name="NoPicksClassifiedsText">
ピックやクラシファイド広告を作成していません。 作成するには、下にある「プラス」ボタンをクリックします。
</string>
+ <string name="NoPicksText">
+ ピックを作成していません。[新規] ボタンをクリックしてピックを作成する。
+ </string>
+ <string name="NoClassifiedsText">
+ クラシファイド広告を作成していません。[新規] ボタンをクリックしてクラシファイド広告を作成する。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
ピック、またはクラシファイド広告がありません
</string>
+ <string name="NoAvatarPicksText">
+ ピックがありません
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ クラシファイド広告がありません
+ </string>
<string name="PicksClassifiedsLoadingText">
ローディング...
</string>
@@ -4557,6 +4584,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="share_alert">
インベントリからここにアイテムをドラッグします
</string>
+ <string name="facebook_post_success">
+ Facebook に投稿しました。
+ </string>
<string name="flickr_post_success">
Flickr に投稿しました。
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_picks.xml b/indra/newview/skins/default/xui/pl/floater_picks.xml
deleted file mode 100644
index a329e834db..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_picks" title="Miejsca" />
diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml
deleted file mode 100644
index 431929420a..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel label="Mój Profil" name="panel_me">
- <panel label="MIEJSCA" name="panel_picks" />
-</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index f086a52dcd..2d4286334f 100644
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
@@ -7,7 +7,7 @@
<spinner label="Górny limit terenu" name="terrain_raise_spin" />
<spinner label="Dolny limit terenu" name="terrain_lower_spin" />
<text name="detail_texture_text">
- Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga)
+ Tekstury terenu (1024x1024, 24 bitowy plik .tga)
</text>
<text name="height_text_lbl">
1 (Nisko)
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index cf033df3c9..90d2d86c02 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -143,7 +143,7 @@ Wersja serwera głosu (Voice Server): [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Błąd sieci: Brak połączenia z siecią, sprawdź status swojego połączenia internetowego.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Logowanie nie powiodło się.
</string>
<string name="Quit">
@@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę.
<string name="GroupNameNone">
(brak danych)
</string>
- <string name="AvalineCaller">
- Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Brak błędu
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
index c50d7dcda0..a43dec4e7b 100644
--- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Landmarks" name="check_landmark"/>
<check_box label="Anotações" name="check_notecard"/>
- <check_box label="Meshes:" name="check_mesh"/>
+ <check_box label="Malhas" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sons" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml
deleted file mode 100644
index 9766196319..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destaques"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
index 6f39635240..90102023a3 100644
--- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar para inventário
</floater.string>
- <text name="desc txt">
- Descrição:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Visualizar relação de aspecto
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa">
- <combo_item name="Unconstrained">
- Sem limites
- </combo_item>
- <combo_item name="1:1" tool_tip="Símbolo ou perfil RW do grupo">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] perfil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Procurar anúncios classificados e marcos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Sobre terrenos">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Perfis destacados">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Salvar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrição:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Visualizar relação de aspecto
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Salvar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_profile.xml b/indra/newview/skins/default/xui/pt/floater_profile.xml
new file mode 100644
index 0000000000..0327211d8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interesses" name="panel_profile_interests"/>
+ <panel label="Destaques" name="panel_profile_picks"/>
+ <panel label="Anúncio" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Observações" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar alterações do perfil e fechar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index e3812ed708..89901b539f 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando e-mail
</string>
+ <string name="facebook_progress_str">
+ Como publicar no Facebook
+ </string>
<string name="profile_progress_str">
Postando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvo no computador
</string>
+ <string name="facebook_succeeded_str">
+ Imagem carregada
+ </string>
<string name="profile_succeeded_str">
Imagem carregada
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvo no computador!
</string>
+ <string name="facebook_failed_str">
+ Falha ao carregar a imagem na sua linha do tempo no Facebook.
+ </string>
<string name="profile_failed_str">
Falha ao carregar a imagem no feed do seu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/pt/menu_name_field.xml b/indra/newview/skins/default/xui/pt/menu_name_field.xml
new file mode 100644
index 0000000000..2157de9813
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Exibir Cópia do Nome" name="copy_display"/>
+ <menu_item_call label="Copiar Nome do Agente" name="copy_name"/>
+ <menu_item_call label="Copiar Id do Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index bd1185bdd2..733ec2c709 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2673,6 +2673,9 @@ Selecione só um objeto.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
index 23e00bfc3a..7b27c811f5 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml
index 64a7d13fdb..f6c6d11b87 100644
--- a/indra/newview/skins/default/xui/pt/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml
@@ -46,7 +46,7 @@ Para obter mais ajuda, passe o mouse sobre as opções.
<check_box label="Qualquer um pode entrar" name="open_enrollement" tool_tip="Controla a entrada de novos membros, com ou sem convite."/>
<check_box label="Taxa de inscrição" name="check_enrollment_fee" tool_tip="Controla a cobrança de uma taxa de associação ao grupo."/>
<spinner label="L$" left_delta="120" name="spin_enrollment_fee" tool_tip="Se a opção &apos;Taxa de associação&apos; estiver marcada, novos membros precisam pagar o valor definido para entrar no grupo." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Os níveis de maturidade determinam o tipo de conteúdo e comportamento permitidos em um grupo" width="170">
+ <combo_box name="group_mature_check" tool_tip="Definir se o seu grupo contém informações classificadas como Moderado" width="170">
<combo_item name="select_mature">
- Selecione o nível de maturidade -
</combo_item>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0490878507
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconhecido"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
+ <button name="profile_btn" tool_tip="Ver perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml
deleted file mode 100644
index 281c886bd4..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Meu perfil" name="panel_me">
- <panel label="MEUS DESTAQUES" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index 2ef01841c5..ce50449b03 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -40,6 +40,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Pessoas que talvez você deseje adicionar"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classified.xml b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
new file mode 100644
index 0000000000..b43a0ad9f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Conteúdo Geral
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]-
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Ativado
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Desativado
+ </panel.string>
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Salvar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Selecione uma imagem"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Localização:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data de criação:"/>
+ <text_editor name="creation_date" tool_tip="Data de criação" value="[date]"/>
+ <text name="price_for_listing_label" value="Preço do anúncio:"/>
+ <text_editor name="price_for_listing" tool_tip="Preço do anúncio.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Cliques:"/>
+ <text_editor name="click_through_text" tool_tip="Dados de click-through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovação automática:"/>
+ <text name="auto_renew" value="Ativado"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrição:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descrição:
+ </text>
+ <text name="location_label">
+ Localização:
+ </text>
+ <text name="classified_location_edit">
+ Carregando...
+ </text>
+ <button label="Usar configuração local" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <icons_combo_box label="Conteúdo Geral" name="content_type_edit">
+ <icons_combo_box.item label="Conteúdo Moderado" name="mature_ci" value="Moderado"/>
+ <icons_combo_box.item label="Conteúdo Geral" name="pg_ci" value="Adequado para menores"/>
+ </icons_combo_box>
+ <check_box label="Renovar automaticamente todas as semanas" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preço do anúncio:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preço do anúncio." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletransportar" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..f8369954fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anúncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nenhum classificado"/>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
index dfc539da66..0fb502e441 100644
--- a/indra/newview/skins/default/xui/it/floater_picks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Preferiti"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_interests.xml b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
new file mode 100644
index 0000000000..edf74115f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interesses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quero:
+ </text>
+ <check_box label="Crie" name="chk0"/>
+ <check_box label="Explore" name="chk1"/>
+ <check_box label="Encontrar" name="chk2"/>
+ <check_box label="Seja contratado" name="chk6"/>
+ <check_box label="Grupo" name="chk3"/>
+ <check_box label="Comprar" name="chk4"/>
+ <check_box label="Venda" name="chk5"/>
+ <check_box label="Contratar" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitetura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planejamento de evento" name="schk2"/>
+ <check_box label="Scripts" name="schk4"/>
+ <check_box label="Personagens personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (carregando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_notes.xml b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
new file mode 100644
index 0000000000..499e371bb7
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anotações e Privacidade" name="panel_notes">
+ <text name="status_message" value="Notas particulares neste avatar:"/>
+ <text name="status_message2" value="Permitir que esse avatar:"/>
+ <check_box label="Ver quando eu estiver conectado" name="status_check"/>
+ <check_box label="Encontre-me no mapa-múndi" name="map_check"/>
+ <check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_pick.xml b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
new file mode 100644
index 0000000000..2dd37b38f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <line_editor name="pick_location">
+ Carregando...
+ </line_editor>
+ <button label="Teletransportar" name="teleport_btn"/>
+ <button label="Mostrar no mapa" name="show_on_map_btn"/>
+ <button label="Definir Localização" name="set_to_curr_location_btn" tool_tip="Usar configuração local"/>
+ <button label="Salvar destaque" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
new file mode 100644
index 0000000000..f9ead974dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destaques" name="panel_picks">
+ <string name="no_picks" value="Nenhum"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Conte a todos sobre os seu lugares favoritos no Second Life.
+ </text>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..8723b1bf58
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Atualmente Online
+ </string>
+ <string name="status_offline">
+ Atualmente Offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nenhum"/>
+ <string name="no_group_text" value="Nenhum"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desenvolvedor"/>
+ <string name="FSSupp" value="Suporte"/>
+ <string name="FSQualityAssurance" value="Caçador de Bug"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Definir nome de tela"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(carregando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status desconhecido"/>
+ <text name="label" value="Aniversário Second Life:"/>
+ <text name="label2" value="Conta:"/>
+ <text name="partner_label" value="Parceiro(a):"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Convidar para entrar no grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Sobre:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar o item:"/>
+ <text name="Give inventory" tool_tip="Arraste e solte o item novo do inventário aqui para dá-los a esta pessoa.">
+ Arraste e solte o item novo do inventário aqui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Localizar no mapa" label_selected="Localizar no mapa" name="show_on_map_btn" tool_tip="Localizar o Residente no mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pague em dinheiro para o Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teletransportar?" label_selected="Teletransportar?" name="teleport" tool_tip="Oferecer teletransporte ao Residente"/>
+ <button label="Mensagem instantânea" label_selected="Mensagem instantânea" name="im" tool_tip="Abrir sessão de mensagem instantânea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Adicionar amigo" label_selected="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear este Residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear este Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar nos resultados de busca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_web.xml b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
new file mode 100644
index 0000000000..0f556c7dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Carregar tempo: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (carregando..)
+ </line_editor>
+ <flyout_button label="Carregar" name="load" tool_tip="Carregar esta página de perfil com navegador embutido">
+ <flyout_button.item label="Abrir no visualizador do navegador" name="open_item"/>
+ <flyout_button.item label="Abrir no navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Abra o perfil da web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 74330a8946..1d312aeed9 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite mais baixo do
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas de terreno (exige arquivos .tga 512x512, 24 bit)
- </text>
+ Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit)
+ </text>
<text name="height_text_lbl">
1 (Baixo)
</text>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index c72a41fd3a..ae452d6a4d 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR]
Placa gráfica: [GRAPHICS_CARD]
</string>
<string name="AboutDriver">
- Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR]
+ Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]
</string>
<string name="AboutOGL">
Versão do OpenGL: [OPENGL_VERSION]
@@ -178,7 +178,7 @@ Versão do servidor de voz: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Erro de rede: Falha de conexão: verifique sua conexão à internet.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Falha do login.
</string>
<string name="Quit">
@@ -313,6 +313,24 @@ Aguarde um minuto antes que tentar logar-se novamente.
<string name="TestingDisconnect">
Teste de desconexão
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando ao Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando do Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema ao conectar ao Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema ao publicar no Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema ao desconectar do Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectando ao Flickr...
</string>
@@ -627,9 +645,6 @@ ser anexado às anotações.
<string name="GroupNameNone">
(nenhum)
</string>
- <string name="AvalineCaller">
- Interlocutor Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nenhum erro
</string>
@@ -2517,9 +2532,21 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="NoPicksClassifiedsText">
Você não criou nenhum Destaque ou Anúncio. Clique no botão &quot;+&quot; para criar um Destaque ou Anúncio.
</string>
+ <string name="NoPicksText">
+ Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher
+ </string>
+ <string name="NoClassifiedsText">
+ Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado
+ </string>
<string name="NoAvatarPicksClassifiedsText">
O usuário não tem nenhum destaque ou anúncio
</string>
+ <string name="NoAvatarPicksText">
+ Usuário não tem escolha
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Usuário não tem anúncio
+ </string>
<string name="PicksClassifiedsLoadingText">
Carregando...
</string>
@@ -4433,6 +4460,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Pasta do inventário &apos;[ITEM_NAME]&apos; oferecida
</string>
+ <string name="facebook_post_success">
+ Você publicou no Facebook.
+ </string>
<string name="flickr_post_success">
Você publicou no Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
index 7c1d3b52c5..bf90d898f9 100644
--- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Жесты" name="check_gesture"/>
<check_box label="Закладки" name="check_landmark"/>
<check_box label="Заметки" name="check_notecard"/>
- <check_box label="Меши" name="check_mesh"/>
+ <check_box label="Полисетки" name="check_mesh"/>
<check_box label="Объекты" name="check_object"/>
<check_box label="Скрипты" name="check_script"/>
<check_box label="Звуки" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml
deleted file mode 100644
index e0ae8d6f03..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Подборка"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
index 46d2a37503..e3921a75ac 100644
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Копировать в инвентарь
</floater.string>
- <text name="desc txt">
- Описание:
- </text>
- <text name="dimensions">
- [WIDTH]пикселей x [HEIGHT]пикселей
- </text>
- <text name="aspect_ratio">
- Просмотр изображения с соотношением сторон
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон">
- <combo_item name="Unconstrained">
- Без ограничения
- </combo_item>
- <combo_item name="1:1" tool_tip="Символ группы или профиль в реальном мире">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Профиль для [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Реклама, поиск и закладки">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="О земле">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Профиль подборки">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Отменить" name="Discard"/>
- <button label="Сохранить как" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Описание:
+ </text>
+ <text name="dimensions">
+ [WIDTH]пикселей x [HEIGHT]пикселей
+ </text>
+ <text name="aspect_ratio">
+ Предварительный просмотр соотношения сторон
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Сбросить" name="Discard"/>
+ <button label="Сохранить как" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_profile.xml b/indra/newview/skins/default/xui/ru/floater_profile.xml
new file mode 100644
index 0000000000..6f8daf0a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Профиль">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Веб" name="panel_profile_web"/>
+ <panel label="Круг интересов" name="panel_profile_interests"/>
+ <panel label="Подборка" name="panel_profile_picks"/>
+ <panel label="Объявление" name="panel_profile_classifieds"/>
+ <panel label="Реальная жизнь" name="panel_profile_firstlife"/>
+ <panel label="Примечания" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Сохранить изменения в профиле и закрыть"/>
+ <button label="Отменить" label_selected="Отменить" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
index 3ac8cb74b4..89a453d9cd 100644
--- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
@@ -67,7 +67,7 @@
<combo_box.item label="Земля &gt; Посягательство &gt; Объекты или текстуры" name="Land__Encroachment__Objects_textures"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Частицы" name="Land__Encroachment__Particles"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Деревья/растения" name="Land__Encroachment__Trees_plants"/>
- <combo_box.item label="Нарушение правил игр на ловкость" name="Wagering_gambling"/>
+ <combo_box.item label="Нарушение игровых правил" name="Wagering_gambling"/>
<combo_box.item label="Другое" name="Other"/>
</combo_box>
<text name="abuser_name_title">
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index 97de279b8f..a796d942f3 100644
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Отправка письма
</string>
+ <string name="facebook_progress_str">
+ Публикация в Facebook
+ </string>
<string name="profile_progress_str">
Публикация
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Сохранение на компьютере
</string>
+ <string name="facebook_succeeded_str">
+ Изображение загружено
+ </string>
<string name="profile_succeeded_str">
Изображение отправлено
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Сохранено на компьютере!
</string>
+ <string name="facebook_failed_str">
+ Не удалось передать изображение на вашу хронику Facebook.
+ </string>
<string name="profile_failed_str">
Не удалось передать изображение в ваш профиль.
</string>
diff --git a/indra/newview/skins/default/xui/ru/menu_name_field.xml b/indra/newview/skins/default/xui/ru/menu_name_field.xml
new file mode 100644
index 0000000000..889f3c37ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Копировать отображаемое имя" name="copy_display"/>
+ <menu_item_call label="Копировать имя агента" name="copy_name"/>
+ <menu_item_call label="Копировать Id агента" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index bfcda798be..e75fd1fd82 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2682,6 +2682,9 @@
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
index a2f06dbadf..ec457c4565 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
@@ -46,8 +46,8 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
- <button label="Отмена" name="cancel_btn"/>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
index 746da8d523..1e4d1346f7 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Сейчас у вас нет друзей по Facebook, которые также были бы жителями Second Life. Предложите своим друзьям по Facebook присоединиться к Second Life!"/>
+ <string name="facebook_friends_empty" value="Сейчас у вас нет друзей в Facebook, которые являются также жителями Second Life. Предложите своим друзьям в Facebook присоединиться к Second Life!"/>
<string name="facebook_friends_no_connected" value="Сейчас вы не подключены к Facebook. Перейдите на вкладку «Статус», чтобы подключиться и включить эту функцию."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Друзья по SL"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
index 143a57fec7..50296778ff 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
@@ -2,19 +2,19 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Разрешение изображения">
<combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <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="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Фильтры изображений">
<combo_box.item label="Без фильтра" name="NoFilter"/>
</combo_box>
- <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкните для обновления"/>
- <button label="Просмотр" name="big_preview_btn" tool_tip="Щелкните для смены вида"/>
+ <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкнуть для обновления"/>
+ <button label="Предпросмотр" name="big_preview_btn" tool_tip="Щелкнуть для смены вида"/>
<text name="caption_label">
Комментарий (не обязательно):
</text>
<button label="Опубликовать" name="post_photo_btn"/>
- <button label="Отмена" name="cancel_photo_btn"/>
+ <button label="Отменить" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
index 7d0917a43a..a7fadca059 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_place">
<text name="place_caption_label">
- Напишите о том, где вы:
+ Сообщите, где вы находитесь:
</text>
<check_box initial_value="false" label="Включить вид места сверху" name="add_place_view_cb"/>
<button label="Опубликовать" name="post_place_btn"/>
- <button label="Отмена" name="cancel_place_btn"/>
+ <button label="Отменить" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
index c651a8087c..826ac6a08c 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Вы подключились к Facebook как:"/>
- <string name="facebook_disconnected" value="Не подключено к Facebook"/>
+ <string name="facebook_disconnected" value="Нет подключения к Facebook"/>
<text name="account_caption_label">
- Не подключено к Facebook.
+ Нет подключения к Facebook.
</text>
<panel name="panel_buttons">
- <button label="Подключение..." name="connect_btn"/>
- <button label="Отключить" name="disconnect_btn"/>
+ <button label="Соединение..." name="connect_btn"/>
+ <button label="Разъединить" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 О публикации в Facebook]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Узнать о публикации в Facebook]
</text>
</panel>
<text name="status_caption_label">
О чем вы думаете?
</text>
<button label="Опубликовать" name="post_status_btn"/>
- <button label="Отмена" name="cancel_status_btn"/>
+ <button label="Отменить" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..3408969d09
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Неизвестно"/>
+ <button name="info_btn" tool_tip="Больше информации"/>
+ <button name="profile_btn" tool_tip="Посмотреть профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml
deleted file mode 100644
index 21a125af87..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Мой профиль" name="panel_me">
- <panel label="МОЯ ПОДБОРКА" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
index 5e3de180f9..331ba889d8 100644
--- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Перетаскивайте сюда закладки, чтобы было удобнее переходить в любимые места в Second Life!">
Избранное
</label>
- <more_button name="&gt;&gt;" tool_tip="Показать больше избранного">
+ <more_button name="&gt;&gt;" tool_tip="Показать больше избранного" width="60">
Больше ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 0812eb7433..8170c8d26f 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Онлайн"/>
<accordion_tab name="tab_all" title="Все"/>
+ <accordion_tab name="tab_suggested_friends" title="С кем вы можете подружиться"/>
</accordion>
</panel>
<panel label="ГРУППЫ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classified.xml b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d3ed685c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Умеренная
+ </panel.string>
+ <panel.string name="type_pg">
+ Общий контент
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ Телепорт [TELEPORT], карта [MAP], профиль [PROFILE]
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Включен
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Отключен
+ </panel.string>
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <string name="publish_label">
+ Опубликовать
+ </string>
+ <string name="save_label">
+ Сохранить
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Щелкнуть для выбора изображения"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Местоположение:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Категория:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Дата создания:"/>
+ <text_editor name="creation_date" tool_tip="Дата создания" value="[date]"/>
+ <text name="price_for_listing_label" value="Стоимость размещения:"/>
+ <text_editor name="price_for_listing" tool_tip="Цена за размещение.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Клики:"/>
+ <text_editor name="click_through_text" tool_tip="Информация о переходах" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Автоматическое продление:"/>
+ <text name="auto_renew" value="Включен"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Описание:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Название:
+ </text>
+ <text name="description_label">
+ Описание:
+ </text>
+ <text name="location_label">
+ Местоположение:
+ </text>
+ <text name="classified_location_edit">
+ загрузка...
+ </text>
+ <button label="Установить в текущее местоположение" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Категория:"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <icons_combo_box label="Общий контент" name="content_type_edit">
+ <icons_combo_box.item label="Умеренный контент" name="mature_ci" value="Возрастной"/>
+ <icons_combo_box.item label="Общий контент" name="pg_ci" value="C разрешения родителей"/>
+ </icons_combo_box>
+ <check_box label="Автоматическое обновление каждую неделю" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Стоимость размещения:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Цена за размещение." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Телепорт" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Карта" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Редактировать" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..fac494682a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Объявление" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Нет рекламы"/>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..f5ac5e906a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_interests.xml b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
new file mode 100644
index 0000000000..ba1c3d0357
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Круг интересов" name="panel_profile_interests">
+ <text name="I Want To:">
+ Я собираюсь:
+ </text>
+ <check_box label="Построить" name="chk0"/>
+ <check_box label="Просмотреть" name="chk1"/>
+ <check_box label="Встретить" name="chk2"/>
+ <check_box label="Получить работу" name="chk6"/>
+ <check_box label="Группа" name="chk3"/>
+ <check_box label="Купить" name="chk4"/>
+ <check_box label="Продать" name="chk5"/>
+ <check_box label="Нанять" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Skills:">
+ Навыки:
+ </text>
+ <check_box label="Текстуры" name="schk0"/>
+ <check_box label="Архитектура" name="schk1"/>
+ <check_box label="Моделирование" name="schk3"/>
+ <check_box label="Планирование мероприятия" name="schk2"/>
+ <check_box label="Создавать сценарии" name="schk4"/>
+ <check_box label="Пользовательские символы" name="schk5"/>
+ <line_editor name="skills_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Languages:">
+ Языки:
+ </text>
+ <line_editor name="languages_edit">
+ (загрузка…)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_notes.xml b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
new file mode 100644
index 0000000000..41117c743a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Примечания и конфиденциальность" name="panel_notes">
+ <text name="status_message" value="Личные заметки об этом аватаре:"/>
+ <text name="status_message2" value="Разрешить этому аватару:"/>
+ <check_box label="Смотреть, когда я в сети" name="status_check"/>
+ <check_box label="Найти меня на карте мира" name="map_check"/>
+ <check_box label="Редактировать, удалять или брать мои объекты" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_pick.xml b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
new file mode 100644
index 0000000000..a2ff5710ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <line_editor name="pick_location">
+ Загрузка...
+ </line_editor>
+ <button label="Телепорт" name="teleport_btn"/>
+ <button label="Показать на карте" name="show_on_map_btn"/>
+ <button label="Указать местоположение" name="set_to_curr_location_btn" tool_tip="Установить в текущее местоположение"/>
+ <button label="Сохранить подборку" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_picks.xml b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
new file mode 100644
index 0000000000..227b3f82b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Подборка" name="panel_picks">
+ <string name="no_picks" value="Нет подборки"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Сообщить всем о ваших избранных службах в Second Life.
+ </text>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..e7a66ba29e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile">
+ <string name="status_online">
+ В настоящее время в режиме онлайн
+ </string>
+ <string name="status_offline">
+ В настоящее время в режиме оффлайн
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Никто"/>
+ <string name="no_group_text" value="Никто"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Разработчик"/>
+ <string name="FSSupp" value="Поддержка"/>
+ <string name="FSQualityAssurance" value="Отладчик"/>
+ <string name="FSGW" value="Межсетевой интерфейс"/>
+ <text name="name_label" value="Имя:"/>
+ <button label="Имя:" name="set_name" tool_tip="Задать отображаемое имя"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(загрузка…)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Статус неизвестен"/>
+ <text name="label" value="Дата рождения в Second Life:"/>
+ <text name="label2" value="Аккаунт:"/>
+ <text name="partner_label" value="Партнер:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Группы:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Пригласить в группу"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="О нас:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Передать вещь:"/>
+ <text name="Give inventory" tool_tip="Сбросить вещи из инвентаря здесь для передачи их этому игроку.">
+ Сбросить вещь из инвентаря здесь.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Найти на карте" label_selected="Найти на карте" name="show_on_map_btn" tool_tip="Найти жителя на карте"/>
+ <button label="Оплатить" label_selected="Оплатить" name="pay" tool_tip="Выплатить деньги резиденту"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Предложить телепорт" label_selected="Предложить телепорт" name="teleport" tool_tip="Предложить телепорт этому жителю"/>
+ <button label="Мгновенное сообщение" label_selected="Мгновенное сообщение" name="im" tool_tip="Начать сеанс IM"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Добавить друга" label_selected="Добавить друга" name="add_friend" tool_tip="Предложить дружбу этому жителю"/>
+ <button label="Заблокировать" name="block" tool_tip="Заблокировать этого жителя"/>
+ <button label="Разблокировать" name="unblock" tool_tip="Разблокировать этого жителя"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Показать в поиске" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_web.xml b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
new file mode 100644
index 0000000000..18a17e2586
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Веб" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Время загрузки: [TIME] секунд"/>
+ <line_editor name="url_edit">
+ (загрузка…)
+ </line_editor>
+ <flyout_button label="Загрузить" name="load" tool_tip="Загрузить эту страницу с профилем с помощью встроенного веб-браузера.">
+ <flyout_button.item label="Открыть в просмотрщике браузера" name="open_item"/>
+ <flyout_button.item label="Открыть во внешнем браузере" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Всплывающий веб-профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index af25565226..76b4f513a8 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>
<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Текстуры ландшафта (требования: 512x512, 24-битные, TGA)
- </text>
+ Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA)
+ </text>
<text name="height_text_lbl">
1 (Низ)
</text>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index ee2dcfe9cc..61d836a2d1 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -187,7 +187,7 @@ SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
<string name="LoginFailedNoNetwork">
Ошибка сети: не удалось установить соединение. Проверьте подключение к сети.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Ошибка входа.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ support@secondlife.com.
<string name="TestingDisconnect">
Тестирование отключения клиента
</string>
+ <string name="SocialFacebookConnecting">
+ Подключение к Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Публикация...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Отключение от Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Проблема с подключением к Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Проблемы при публикации в Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Проблема с отключением от Facebook
+ </string>
<string name="SocialFlickrConnecting">
Подключение к Flickr...
</string>
@@ -671,9 +689,6 @@ support@secondlife.com.
<string name="GroupNameNone">
(нет)
</string>
- <string name="AvalineCaller">
- [ORDER] абонента Avaline
- </string>
<string name="AssetErrorNone">
Ошибок нет
</string>
@@ -2576,9 +2591,21 @@ support@secondlife.com.
<string name="NoPicksClassifiedsText">
Вы не создали подборки или рекламы. Нажмите кнопку со знаком «плюс» ниже, чтобы создать подборку или рекламу
</string>
+ <string name="NoPicksText">
+ Вы не сделали никакой подборки. Нажмите кнопку Создать, чтобы сделать подборку.
+ </string>
+ <string name="NoClassifiedsText">
+ Вы не сделали никакой рекламы. Нажмите кнопку Создать, чтобы сделать рекламу.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
У жителя нет подборки или рекламы
</string>
+ <string name="NoAvatarPicksText">
+ У пользователя нет подборки
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ У пользователя нет объявлений
+ </string>
<string name="PicksClassifiedsLoadingText">
Загрузка...
</string>
@@ -4553,6 +4580,9 @@ support@secondlife.com.
<string name="share_alert">
Перетаскивайте вещи из инвентаря сюда
</string>
+ <string name="facebook_post_success">
+ Вы опубликовали сообщение в Facebook.
+ </string>
<string name="flickr_post_success">
Вы опубликовали сообщение в Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_facebook.xml b/indra/newview/skins/default/xui/tr/floater_facebook.xml
index 656a4a81c9..d8cbd84ed1 100644
--- a/indra/newview/skins/default/xui/tr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/tr/floater_facebook.xml
@@ -3,7 +3,7 @@
<tab_container name="tabs">
<panel label="DURUM" name="panel_facebook_status"/>
<panel label="FOTOĞRAF" name="panel_facebook_photo"/>
- <panel label="KONUMA GİRİŞ YAPIN" name="panel_facebook_place"/>
+ <panel label="GİRİŞ YAP" name="panel_facebook_place"/>
<panel label="ARKADAŞLAR" name="panel_facebook_friends"/>
</tab_container>
<text name="connection_error_text">
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
index accb1ed71c..caa8497d3a 100644
--- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Mimikler" name="check_gesture"/>
<check_box label="Yer İmleri" name="check_landmark"/>
<check_box label="Not Kartları" name="check_notecard"/>
- <check_box label="Örgüler" name="check_mesh"/>
+ <check_box label="Ağlar" name="check_mesh"/>
<check_box label="Nesneler" name="check_object"/>
<check_box label="Komut Dosyaları" name="check_script"/>
<check_box label="Sesler" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
deleted file mode 100644
index 5aee6ae091..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Seçimler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
index 8302c62070..8ba9123545 100644
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Envantere Kopyala
</floater.string>
- <text name="desc txt">
- Açıklama:
- </text>
- <text name="dimensions">
- [WIDTH] pks x [HEIGHT] pks
- </text>
- <text name="aspect_ratio">
- En boy oranını önizle
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle">
- <combo_item name="Unconstrained">
- Kısıtsız
- </combo_item>
- <combo_item name="1:1" tool_tip="Grup işaretleri veya Real World profili">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] profili">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="İlanlar ve arama listeleri, yer imleri">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Arazi hakkında">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profil seçmeleri">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="Tamam" name="Keep"/>
- <button label="At" name="Discard"/>
- <button label="Farklı Kaydet" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Açıklama:
+ </text>
+ <text name="dimensions">
+ [WIDTH]pks x [HEIGHT]pks
+ </text>
+ <text name="aspect_ratio">
+ En boy oranını önizle
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="Tamam" name="Keep"/>
+ <button label="At" name="Discard"/>
+ <button label="Farklı Kaydet" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_profile.xml b/indra/newview/skins/default/xui/tr/floater_profile.xml
new file mode 100644
index 0000000000..bb158ddf66
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="İlgi alanları" name="panel_profile_interests"/>
+ <panel label="Favoriler" name="panel_profile_picks"/>
+ <panel label="İlan" name="panel_profile_classifieds"/>
+ <panel label="Gerçek Hayat" name="panel_profile_firstlife"/>
+ <panel label="Notlar" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="Tamam" name="ok_btn" tool_tip="Değişiklikleri profile kaydet ve kapat"/>
+ <button label="İptal Et" label_selected="İptal Et" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index be6c58e8cf..8496194700 100644
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-posta Gönderiliyor
</string>
+ <string name="facebook_progress_str">
+ Facebook&apos;ta yayınlanıyor
+ </string>
<string name="profile_progress_str">
Yayınlanıyor
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Bilgisayara Kaydediliyor
</string>
+ <string name="facebook_succeeded_str">
+ Görüntü yüklendi
+ </string>
<string name="profile_succeeded_str">
Görüntü yüklendi
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Bilgisayara Kaydedildi!
</string>
+ <string name="facebook_failed_str">
+ Görüntü Facebook zaman tünelinize yüklenemedi.
+ </string>
<string name="profile_failed_str">
Görüntü Profil Akışınıza yüklenemedi.
</string>
diff --git a/indra/newview/skins/default/xui/tr/menu_name_field.xml b/indra/newview/skins/default/xui/tr/menu_name_field.xml
new file mode 100644
index 0000000000..b1afd737c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Görünen Adı Kopyala" name="copy_display"/>
+ <menu_item_call label="Aracı Adını Kopyala" name="copy_name"/>
+ <menu_item_call label="Aracı Kimliğini Kopyala" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 5403a78f22..17d2969d19 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2682,6 +2682,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
index fc444f21f6..78c34a3ac0 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="İptal Et" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
index 8184d6d7cf..edbe87d74c 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Şu an için aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızı bugün Second Life&apos;a katılmaya davet edin!"/>
+ <string name="facebook_friends_empty" value="Şu anda aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızdan bugün Second Life&apos;a katılmalarını isteyin!"/>
<string name="facebook_friends_no_connected" value="Şu anda Facebook&apos;a bağlı değilsiniz. Bağlanmak ve bu özelliği etkinleştirmek için lütfen Durum sekmesine gidin."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL arkadaşları"/>
<accordion_tab name="tab_suggested_friends" title="Bu kişileri SL arkadaşları olarak ekle"/>
</accordion>
<text name="facebook_friends_status">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
index d772aff937..e3150f258d 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Görüntü çözünürlüğü">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="Geçerli Pencere" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
@@ -11,10 +11,10 @@
<combo_box.item label="Filtre Yok" name="NoFilter"/>
</combo_box>
<button label="Yenile" name="new_snapshot_btn" tool_tip="Yenilemek için tıklayın"/>
- <button label="Önizleme" name="big_preview_btn" tool_tip="Önizleme ayarları arasında geçiş yapmak için tıklayın"/>
+ <button label="Önizleme" name="big_preview_btn" tool_tip="Önizlemeye geçmek için tıklayın"/>
<text name="caption_label">
Yorum (isteğe bağlı):
</text>
<button label="Yayınla" name="post_photo_btn"/>
- <button label="İptal" name="cancel_photo_btn"/>
+ <button label="İptal Et" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
index 85b401a1a0..96c34d03d0 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="Konumun üstten görünümünü ekle" name="add_place_view_cb"/>
<button label="Yayınla" name="post_place_btn"/>
- <button label="İptal" name="cancel_place_btn"/>
+ <button label="İptal Et" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
index e6feff5949..f5dba088de 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Facebook&apos;a şu kimlikle bağlandınız:"/>
- <string name="facebook_disconnected" value="Facebook&apos;a bağlanılmadı"/>
+ <string name="facebook_disconnected" value="Facebook&apos;a bağlanılamadı"/>
<text name="account_caption_label">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
<panel name="panel_buttons">
<button label="Bağlan..." name="connect_btn"/>
@@ -13,8 +13,8 @@
</text>
</panel>
<text name="status_caption_label">
- Ne düşünüyorsunuz?
+ Aklınızdan ne geçiyor?
</text>
<button label="Yayınla" name="post_status_btn"/>
- <button label="İptal" name="cancel_status_btn"/>
+ <button label="İptal Et" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml
index c666778c69..5578b36f3f 100644
--- a/indra/newview/skins/default/xui/tr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml
@@ -45,7 +45,7 @@ Daha fazla yardım edinmek için farenizi seçeneklerin üzerine getirin.
<check_box label="Herkes katılabilir" name="open_enrollement" tool_tip="Bu grubun davet edilmeden yeni üyelerin katılmasına imkan tanıyıp tanımayacağını belirler."/>
<check_box label="Katılma ücreti" name="check_enrollment_fee" tool_tip="Bu gruba katılmak için bir kayıt ücretinin gerekip gerekmeyeceğini belirler"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Kayıt Ücreti işaretlendiğinde yeni üyeler gruba katılmak için bu ücreti ödemelidir."/>
- <combo_box name="group_mature_check" tool_tip="Erişkinlik dereceleri bir grupta izin verilen içerik ve davranış türlerini belirler">
+ <combo_box name="group_mature_check" tool_tip="Grubunuzun Orta olarak sınıflandırılmış bilgiler içerip içermeyeceğini belirler">
<combo_item name="select_mature">
- Erişkinlik seviyesini seçin -
</combo_item>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0ed905ed35
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Bilinmiyor"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
+ <button name="profile_btn" tool_tip="Profili görüntüle"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
deleted file mode 100644
index d9e79d171c..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Profilim" name="panel_me">
- <panel label="SEÇTİKLERİM" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
index 8d43e3fb5a..ae9bc33bfa 100644
--- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla erişmek için Yer İmlerini buraya sürükleyin!">
Favoriler Çubuğu
</label>
- <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster">
+ <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster" width="65">
Daha Fazla ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 25d29fcbb5..acbcd2a544 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -40,6 +40,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Çevrimiçi"/>
<accordion_tab name="tab_all" title="Tümü"/>
+ <accordion_tab name="tab_suggested_friends" title="Arkadaş olmak isteyebileceğiniz kişiler"/>
</accordion>
</panel>
<panel label="GRUPLAR" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classified.xml b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
new file mode 100644
index 0000000000..805de24c11
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Orta
+ </panel.string>
+ <panel.string name="type_pg">
+ Genel İçerik
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] ışınlanma, [MAP] harita, [PROFILE] profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Etkin
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Devre dışı
+ </panel.string>
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <string name="publish_label">
+ Yayınla
+ </string>
+ <string name="save_label">
+ Kaydet
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Bir görüntü seçmek için tıklayın"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Konum:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="İçerik Türü:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategori:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Oluşturma tarihi:"/>
+ <text_editor name="creation_date" tool_tip="Oluşturma tarihi" value="[date]"/>
+ <text name="price_for_listing_label" value="İlan fiyatı:"/>
+ <text_editor name="price_for_listing" tool_tip="İlan fiyatı.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Tıklama sayısı:"/>
+ <text_editor name="click_through_text" tool_tip="Tıklama verileri" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Otomatik yenileme:"/>
+ <text name="auto_renew" value="Etkin"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Açıklama:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Başlık:
+ </text>
+ <text name="description_label">
+ Açıklama:
+ </text>
+ <text name="location_label">
+ Konum:
+ </text>
+ <text name="classified_location_edit">
+ yükleniyor...
+ </text>
+ <button label="Geçerli Konuma Ayarla" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategori:"/>
+ <text name="content_type_label" value="İçerik türü:"/>
+ <icons_combo_box label="Genel İçerik" name="content_type_edit">
+ <icons_combo_box.item label="Orta İçerik" name="mature_ci" value="Yetişkin"/>
+ <icons_combo_box.item label="Genel İçerik" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Her hafta otomatik yenile" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="İlan fiyatı:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="İlan fiyatı." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Işınlanma" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Harita" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Düzenle" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="İptal Et" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..0edae1ab2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlan" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="İlan Yok"/>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..0f65090209
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_interests.xml b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
new file mode 100644
index 0000000000..b068aa3dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlgi alanları" name="panel_profile_interests">
+ <text name="I Want To:">
+ Şunu Yapmak İstiyorum:
+ </text>
+ <check_box label="İnşa Et" name="chk0"/>
+ <check_box label="Keşfet" name="chk1"/>
+ <check_box label="Tanış" name="chk2"/>
+ <check_box label="İşe Gir" name="chk6"/>
+ <check_box label="Gruplandır" name="chk3"/>
+ <check_box label="Satın Al" name="chk4"/>
+ <check_box label="Sat" name="chk5"/>
+ <check_box label="İşe Al" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Skills:">
+ Beceriler:
+ </text>
+ <check_box label="Dokular" name="schk0"/>
+ <check_box label="Mimari" name="schk1"/>
+ <check_box label="Modelleme" name="schk3"/>
+ <check_box label="Etkinlik Planlama" name="schk2"/>
+ <check_box label="Kodlama" name="schk4"/>
+ <check_box label="Özel Karakterler" name="schk5"/>
+ <line_editor name="skills_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Languages:">
+ Diller:
+ </text>
+ <line_editor name="languages_edit">
+ (yükleniyor...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_notes.xml b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
new file mode 100644
index 0000000000..fff75dd685
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notlar ve Gizlilik" name="panel_notes">
+ <text name="status_message" value="Bu avatar ile ilgili özel notlar:"/>
+ <text name="status_message2" value="Bu avatar için şunlara izin ver:"/>
+ <check_box label="Çevrimiçi olduğumu görme" name="status_check"/>
+ <check_box label="Beni dünya haritasında bulma" name="map_check"/>
+ <check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_pick.xml b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
new file mode 100644
index 0000000000..d42c1eff7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <line_editor name="pick_location">
+ Yükleniyor...
+ </line_editor>
+ <button label="Işınlanma" name="teleport_btn"/>
+ <button label="Haritada Göster" name="show_on_map_btn"/>
+ <button label="Konumu Ayarla" name="set_to_curr_location_btn" tool_tip="Geçerli Konuma Ayarla"/>
+ <button label="Favoriyi Kaydet" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
new file mode 100644
index 0000000000..7222a2fc2e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoriler" name="panel_picks">
+ <string name="no_picks" value="Favori Yok"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life&apos;ta favori yerlerinizi herkese anlatın!
+ </text>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..00e81d005e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Şu Anda Çevrimiçi
+ </string>
+ <string name="status_offline">
+ Şu Anda Çevrimdışı
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Yok"/>
+ <string name="no_group_text" value="Yok"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Geliştirici"/>
+ <string name="FSSupp" value="Destek"/>
+ <string name="FSQualityAssurance" value="Böcek bilimci"/>
+ <string name="FSGW" value="Ağ geçidi"/>
+ <text name="name_label" value="Ad:"/>
+ <button label="Ad:" name="set_name" tool_tip="Görünen Adı Ayarla"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(yükleniyor...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Durum Bilinmiyor"/>
+ <text name="label" value="Second Life Doğum Tarihi:"/>
+ <text name="label2" value="Hesap:"/>
+ <text name="partner_label" value="Ortak:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruplar:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Gruba Davet Et"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Hakkında:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Öğe ver:"/>
+ <text name="Give inventory" tool_tip="Envanter öğelerini bu kişiye vermek için buraya bırakın.">
+ Envanter öğesini buraya bırakın.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Haritada Bul" label_selected="Haritada Bul" name="show_on_map_btn" tool_tip="Sakini haritada bul"/>
+ <button label="Öde" label_selected="Öde" name="pay" tool_tip="Sakine para öde"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Işınlanma Teklif Et" label_selected="Işınlanma Teklif Et" name="teleport" tool_tip="Sakine ışınlanma teklif et"/>
+ <button label="Anlık İleti" label_selected="Anlık İleti" name="im" tool_tip="Anlık ileti oturumu aç"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Arkadaş Ekle" label_selected="Arkadaş Ekle" name="add_friend" tool_tip="Sakine arkadaşlık teklif et"/>
+ <button label="Engelle" name="block" tool_tip="Bu Sakini engelle"/>
+ <button label="Engellemeyi Kaldır" name="unblock" tool_tip="Bu Sakinin engellemesini kaldır"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Aramada göster" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_web.xml b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
new file mode 100644
index 0000000000..265b1fee7e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Yükleme Süresi: [TIME] saniye"/>
+ <line_editor name="url_edit">
+ (yükleniyor..)
+ </line_editor>
+ <flyout_button label="Yükle" name="load" tool_tip="Bu profil sayfasını tümleşik web tarayıcı ile yükleyin.">
+ <flyout_button.item label="Görüntüleyici içindeki tarayıcıda aç" name="open_item"/>
+ <flyout_button.item label="Dış tarayıcıda aç" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Açılır web profili"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index 3226ee008e..e25047301d 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>
<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir)
- </text>
+ Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir)
+ </text>
<text name="height_text_lbl">
1 (Düşük)
</text>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 982de76a5b..e709a4c5d6 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -187,7 +187,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION]
<string name="LoginFailedNoNetwork">
Ağ hatası: Bağlantı kurulamadı, lütfen ağ bağlantınızı kontrol edin.
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
Oturum açılamadı.
</string>
<string name="Quit">
@@ -357,6 +357,24 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="TestingDisconnect">
Görüntüleyici bağlantısının kesilmesi test ediliyor
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook ile bağlantı kuruluyor...
+ </string>
+ <string name="SocialFacebookPosting">
+ Yayınlanıyor...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook bağlantısı kesiliyor...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook ile bağlantı kurulurken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook&apos;ta yayınlarken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook bağlantısı kesilirken sorun oluştu
+ </string>
<string name="SocialFlickrConnecting">
Flickr bağlantısı kuruluyor...
</string>
@@ -671,9 +689,6 @@ kartlarına eklenebilir.
<string name="GroupNameNone">
(hiçbiri)
</string>
- <string name="AvalineCaller">
- Avaline Arayanı [ORDER]
- </string>
<string name="AssetErrorNone">
Hata yok
</string>
@@ -2576,9 +2591,21 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="NoPicksClassifiedsText">
Herhangi bir Seçme veya İlan oluşturmadınız. Bir Seçme veya İlan oluşturmak için aşağıdaki Artı düğmesine tıklayın.
</string>
+ <string name="NoPicksText">
+ Herhangi bir Favori oluşturmadınız. Bir Favori oluşturmak için Yeni düğmesine tıklayın.
+ </string>
+ <string name="NoClassifiedsText">
+ Herhangi bir İlan oluşturmadınız. Bir İlan oluşturmak için Yeni düğmesine tıklayın.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Kullanıcının herhangi bir seçmesi veya ilanı yok
</string>
+ <string name="NoAvatarPicksText">
+ Kullanıcının favorisi yok
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Kullanıcının ilanı yok
+ </string>
<string name="PicksClassifiedsLoadingText">
Yükleniyor...
</string>
@@ -4556,6 +4583,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="share_alert">
Envanterinizden buraya öğeler sürükleyin
</string>
+ <string name="facebook_post_success">
+ Facebook&apos;ta yayınladınız.
+ </string>
<string name="flickr_post_success">
Flickr&apos;da yayınladınız.
</string>
diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml
deleted file mode 100644
index a8bfcd99e3..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="精選地點"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
index 2b6eac48b3..9213cc212d 100644
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
覆製到收納區
</floater.string>
- <text name="desc txt">
- 描述:
- </text>
- <text name="dimensions">
- [WIDTH]像素 x [HEIGHT]像素
- </text>
- <text name="aspect_ratio">
- 預覽長寬比
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽">
- <combo_item name="Unconstrained">
- 不受限
- </combo_item>
- <combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地資料">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="個人檔案精選">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="確定" name="Keep"/>
- <button label="丟棄" name="Discard"/>
- <button label="另存為" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 描述:
+ </text>
+ <text name="dimensions">
+ [WIDTH]像素 x [HEIGHT]像素
+ </text>
+ <text name="aspect_ratio">
+ 預覽長寬比
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="確定" name="Keep"/>
+ <button label="丟棄" name="Discard"/>
+ <button label="另存為" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_profile.xml b/indra/newview/skins/default/xui/zh/floater_profile.xml
new file mode 100644
index 0000000000..0f73f527a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="簡覽">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="第二人生" name="panel_profile_secondlife"/>
+ <panel label="網頁" name="panel_profile_web"/>
+ <panel label="興趣" name="panel_profile_interests"/>
+ <panel label="精選地點" name="panel_profile_picks"/>
+ <panel label="分類廣告" name="panel_profile_classifieds"/>
+ <panel label="真實世界" name="panel_profile_firstlife"/>
+ <panel label="筆記" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="確定" name="ok_btn" tool_tip="儲存變更到個人檔案後關閉"/>
+ <button label="取消" label_selected="取消" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 4090248083..6e1a156762 100644
--- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
正在發送電郵
</string>
+ <string name="facebook_progress_str">
+ 發佈到臉書
+ </string>
<string name="profile_progress_str">
發佈
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
正在存到電腦
</string>
+ <string name="facebook_succeeded_str">
+ 圖像已上傳
+ </string>
<string name="profile_succeeded_str">
圖像已上傳
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
成功存入電腦!
</string>
+ <string name="facebook_failed_str">
+ 上傳圖像到你的臉書時間線時失敗。
+ </string>
<string name="profile_failed_str">
上傳圖像到你的檔案訊息發佈時出錯。
</string>
diff --git a/indra/newview/skins/default/xui/zh/menu_name_field.xml b/indra/newview/skins/default/xui/zh/menu_name_field.xml
new file mode 100644
index 0000000000..5eaf3461cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="複製顯示名稱" name="copy_display"/>
+ <menu_item_call label="複製代理名稱" name="copy_name"/>
+ <menu_item_call label="複製代理ID" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index cfde824349..4d0f1cb85b 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2666,6 +2666,9 @@ SHA1 指紋:[MD5_DIGEST]
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
index b06ece02ad..4d3248db46 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="取消" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fec4bb572a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="未知"/>
+ <button name="info_btn" tool_tip="詳情"/>
+ <button name="profile_btn" tool_tip="察看檔案"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml
deleted file mode 100644
index aad1348e46..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="我的個人檔案" name="panel_me">
- <panel label="我的精選地點" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index b0e60218cf..b95dd96026 100644
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="上線"/>
<accordion_tab name="tab_all" title="全部"/>
+ <accordion_tab name="tab_suggested_friends" title="你可能想要加為好友的人"/>
</accordion>
</panel>
<panel label="群組" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classified.xml b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
new file mode 100644
index 0000000000..4eee4e8855
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ 適度成人
+ </panel.string>
+ <panel.string name="type_pg">
+ 一般普級內容
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 已啟用
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 已停用
+ </panel.string>
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <string name="publish_label">
+ 發布
+ </string>
+ <string name="save_label">
+ 儲存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="位置:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="分類:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="建立日期:"/>
+ <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <text_editor name="price_for_listing" tool_tip="刊登費。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="點按狀況:"/>
+ <text_editor name="click_through_text" tool_tip="點按資料" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動續訂:"/>
+ <text name="auto_renew" value="已啟用"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="描述:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ 標題:
+ </text>
+ <text name="description_label">
+ 描述:
+ </text>
+ <text name="location_label">
+ 位置:
+ </text>
+ <text name="classified_location_edit">
+ 載入中...
+ </text>
+ <button label="設定為目前位置" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="分類:"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <icons_combo_box label="一般普級內容" name="content_type_edit">
+ <icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/>
+ <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/>
+ </icons_combo_box>
+ <check_box label="每星期自動續訂" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="刊登費:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="刊登費。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="瞬間傳送" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地圖" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編輯" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="取消" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..89b5cdf641
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="分類廣告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="禁止個人廣告"/>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..9370661d7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_interests.xml b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
new file mode 100644
index 0000000000..150f3cca4f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="興趣" name="panel_profile_interests">
+ <text name="I Want To:">
+ 我想要:
+ </text>
+ <check_box label="建造" name="chk0"/>
+ <check_box label="探索" name="chk1"/>
+ <check_box label="見面" name="chk2"/>
+ <check_box label="受雇" name="chk6"/>
+ <check_box label="群組" name="chk3"/>
+ <check_box label="購買" name="chk4"/>
+ <check_box label="出售" name="chk5"/>
+ <check_box label="招人" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Skills:">
+ 技能:
+ </text>
+ <check_box label="材質" name="schk0"/>
+ <check_box label="架構" name="schk1"/>
+ <check_box label="建模" name="schk3"/>
+ <check_box label="計畫活動" name="schk2"/>
+ <check_box label="建腳本" name="schk4"/>
+ <check_box label="定製角色" name="schk5"/>
+ <line_editor name="skills_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Languages:">
+ 語言:
+ </text>
+ <line_editor name="languages_edit">
+ (載入中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_notes.xml b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
new file mode 100644
index 0000000000..17e1a997da
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="筆記和隱私" name="panel_notes">
+ <text name="status_message" value="關於這化身的私人筆記:"/>
+ <text name="status_message2" value="允許這個化身:"/>
+ <check_box label="看見我何時上線" name="status_check"/>
+ <check_box label="在世界地圖上找到我" name="map_check"/>
+ <check_box label="邊輯,刪除或取下我的物件" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_pick.xml b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
new file mode 100644
index 0000000000..5f8d6a2ba5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ 載入中…
+ </line_editor>
+ <button label="瞬間傳送" name="teleport_btn"/>
+ <button label="顯示在地圖上" name="show_on_map_btn"/>
+ <button label="設定位置" name="set_to_curr_location_btn" tool_tip="設定為目前位置"/>
+ <button label="儲存精選地點" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
new file mode 100644
index 0000000000..8f189d1308
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="精選地點" name="panel_picks">
+ <string name="no_picks" value="無精選地點"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ 告訴大家你在Second Life中最愛的去處。
+ </text>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..da4aafce55
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile">
+ <string name="status_online">
+ 目前在線
+ </string>
+ <string name="status_offline">
+ 目前離線
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="無"/>
+ <string name="no_group_text" value="無"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開發者"/>
+ <string name="FSSupp" value="支援"/>
+ <string name="FSQualityAssurance" value="除錯獵人"/>
+ <string name="FSGW" value="網關"/>
+ <text name="name_label" value="名稱:"/>
+ <button label="名稱:" name="set_name" tool_tip="設定顯示名稱"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(載入中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="狀態不明"/>
+ <text name="label" value="Second Life生日:"/>
+ <text name="label2" value="帳戶:"/>
+ <text name="partner_label" value="伴侶:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="群組:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="邀請加入群組"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="關於:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="贈與物品:"/>
+ <text name="Give inventory" tool_tip="把收納區物品放到這裡,送給此人。">
+ 把收納區物品放到這裡。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="在地圖上查找" label_selected="在地圖上查找" name="show_on_map_btn" tool_tip="在地圖上找出這個居民"/>
+ <button label="支付" label_selected="支付" name="pay" tool_tip="付款給這個居民"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="發出瞬間傳送邀請" label_selected="發出瞬間傳送邀請" name="teleport" tool_tip="向這個居民發出瞬間傳送邀請"/>
+ <button label="即時訊息" label_selected="即時訊息" name="im" tool_tip="開啟即時訊息會話"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="加為朋友" label_selected="加為朋友" name="add_friend" tool_tip="向這個居民發出交友邀請"/>
+ <button label="封鎖" name="block" tool_tip="封鎖這位居民"/>
+ <button label="解除封鎖" name="unblock" tool_tip="不再封鎖這位居民"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="在搜尋結果中顯示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_web.xml b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
new file mode 100644
index 0000000000..566651dceb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="網頁" name="panel_profile_web">
+ <panel.string name="LoadTime" value="載入時間:[TIME]秒"/>
+ <line_editor name="url_edit">
+ (載入中…)
+ </line_editor>
+ <flyout_button label="載入" name="load" tool_tip="用內嵌瀏覽器載入此個人檔案頁面。">
+ <flyout_button.item label="開啓内部瀏覽器" name="open_item"/>
+ <flyout_button.item label="開啓外部瀏覽器" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="彈出式個人檔案網頁"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 85e759e445..81bce46876 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形提升限制" name="terrain_raise_spin"/>
<spinner label="地形降低限制" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形材質(須 512x512,24 位元 .tga 檔格式)
+ 地形材質(須 1024x1024,24 位元 .tga 檔格式)
</text>
<text name="height_text_lbl">
1(低)
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 3221cde3b7..bdb16c9bf1 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -187,7 +187,7 @@ LibVLC版本:[LIBVLC_VERSION]N]
<string name="LoginFailedNoNetwork">
網路錯誤:無法建立連線,請檢查網路連線是否正常。
</string>
- <string name="LoginFailed">
+ <string name="LoginFailedHeader">
登入失敗。
</string>
<string name="Quit">
@@ -353,6 +353,24 @@ http://secondlife.com/viewer-access-faq
<string name="TestingDisconnect">
測試瀏覽器斷線
</string>
+ <string name="SocialFacebookConnecting">
+ 連通臉書中…
+ </string>
+ <string name="SocialFacebookPosting">
+ 發佈中…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ 臉書連通中斷中…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ 連通臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ 發佈到臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ 試圖中斷臉書連通時出問題
+ </string>
<string name="SocialFlickrConnecting">
連通 Flickr 中…
</string>
@@ -667,9 +685,6 @@ http://secondlife.com/viewer-access-faq
<string name="GroupNameNone">
(無)
</string>
- <string name="AvalineCaller">
- Avaline 通話者 [ORDER]
- </string>
<string name="AssetErrorNone">
無錯誤
</string>
@@ -2569,9 +2584,21 @@ http://secondlife.com/support 求助解決問題。
<string name="NoPicksClassifiedsText">
你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。
</string>
+ <string name="NoPicksText">
+ 你尚未建立任何精選地點。 點按「新增」按鈕建立精選地點。
+ </string>
+ <string name="NoClassifiedsText">
+ 你尚未建立任何分類廣告。 點按「新增」按鈕建立分類廣告。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
使用者無精選地點或個人廣告
</string>
+ <string name="NoAvatarPicksText">
+ 使用者沒有精選地點
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ 使用者沒有分類廣告
+ </string>
<string name="PicksClassifiedsLoadingText">
載入中...
</string>
@@ -4549,6 +4576,9 @@ http://secondlife.com/support 求助解決問題。
<string name="share_alert">
將收納區物品拖曳到這裡
</string>
+ <string name="facebook_post_success">
+ 成功發佈到臉書。
+ </string>
<string name="flickr_post_success">
成功發佈到 Flickr。
</string>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index a52c3dcef9..696fe3536c 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -223,6 +223,7 @@ bool llHashedUniqueID(unsigned char* id)
#include "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
bool LLAppViewer::isUpdaterMissing() { return true; }
+bool LLAppViewer::waitForUpdater() { return false; }
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de5ac5ed3d..59eb18b734 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -568,6 +568,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
@@ -954,6 +955,7 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
+ self.path("cube.dae")
self.path("SecondLife.nib")
with self.prefix(src=pkgdir,dst=""):
@@ -1427,6 +1429,7 @@ class LinuxManifest(ViewerManifest):
print("Skipping llcommon.so (assuming llcommon was linked statically)")
self.path("featuretable_linux.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")